Confusing Java synchronized method, synchronized(this), and synchronized class
Confusing Java synchronized method, synchronized(this), and synchronized class
I'm very confused because of Java's synchronized concept.
Let's assume the below class:
class MyClass
public synchronized void foo() //do something
public void bar()
synchronized(this) //do something
public void normal() //do something
As far as I know, the foo
and bar
methods work the same.
foo
bar
But, after thread A enters the bar
method and synchronizes the instance by synchronized(this)
, can any thread call the normal method?
bar
synchronized(this)
As far as I know, some threads can call the normal method regardless of calling the foo
method. But I'm not sure when the bar
method is called because it synchronized an instance.
foo
bar
Also, let's assume the below method:
class StaticMyClass
public static synchronized void fooStatic() //do something
publi static void barStatic()
synchronized(StaticMyClass.class) //do something
public static void normalStatic() //do something
Here, there is the same question. After thread A enters the critical section, which is synchronized(StaticMyClass.class)
or the fooStatic
method, can any thread call normalStatic
?
I think that fooStatic
and normalStatic
can be called independently, but barStatic
and normalStatic
can't. If it is wrong, why?
synchronized(StaticMyClass.class)
fooStatic
normalStatic
fooStatic
normalStatic
barStatic
normalStatic
I appreciate your help.
Edit:
My confused point is that I am not sure that synchronized(this)
is same as synchronized(myClassInstance)
.
synchronized(this)
synchronized(myClassInstance)
MyClass my = new MyClass();
synchronized(my)
//do something, Any other thread can't access my.normal(), is it right?
class MyClass
public synchronized void foo() //do something
public void bar()
synchronized(this)
//do something, isn't this same as above synchronized(my)?
public void normal() //do something
synchronized(myClassInstance)
my.normal()
normal
/* isn't this same as above synchronized(my)? */
bar()
@Stephen C I apologize lack of explanation. I will edit again
– Hacking J
Sep 2 at 4:34
@HackingJ No problem, glad to help out.
– LAD
Sep 2 at 21:00
3 Answers
3
As far as I know, foo
and bar
methods work same.
foo
bar
Correct. They both synchronize on this
.
this
After thread A enter the bar
method and synchronize the instance by synchronized(this)
, can any thread call normal
method?
bar
synchronized(this)
normal
Yes. Correct.
As far as I know, some thread can call normal
method regardless calling foo
method. but I'm not sure when the bar method is called. because it synchronized a instance.
normal
foo
foo
and bar
are the same. They are both synchronizing on this
. The normal
method is not synchronizing on anything. Therefore it can be called at any time from anywhere and it will not blocked, either at the point of the method call, or internally.
foo
bar
this
normal
In your terminology, the normal
method is not a critical section1.
normal
Second example with statics
Here, there is same question. after thread A enter the critical section which is synchronized(StaticMyClass.class)
or fooStatic
method, can any thread call normalStatic
?
synchronized(StaticMyClass.class)
fooStatic
normalStatic
Yes. The fooStatic
and barStatic
will both synchronize on StaticMyClass.class
.
fooStatic
barStatic
StaticMyClass.class
I think, call fooStatic
and normalStatic
can be called independently, but barStatic
and normalStatic
can't.
fooStatic
normalStatic
barStatic
normalStatic
Incorrect. The normalStatic
is not blocked by fooStatic
OR barStatic
.
normalStatic
fooStatic
barStatic
I'm not sure where you got the idea that normalStatic
might be blocked ... but it is a normal method call and doesn't acquire any intrinsic locks, so it cannot be blocked on a lock.
normalStatic
Your third example is unclear. The code shows one thing, but the question asks something different / unrelated.
1 - It might get a bit confusing if (say) foo
or bar
called normal
while holding the intrinsic lock. Then the normal
code will be effectively in the critical section because the caller holds the lock. But it (normal
) typically won't know this. This is why I prefer to avoid the "critical section" terminology.
foo
bar
normal
normal
normal
If you do not specify who is the monitor, with instance methods the monitor is the instance (this), and with static methods the monitor is the class (YourClass.class).
This code
public synchronized void foo() //do something
It is the same than this
public void foo()
synchronized(this) //do something
and this code
public static synchronized void fooStatic() //do something
is the same than this
public static void fooStatic()
synchronized(StaticMyClass.class) //do something
So, in both cases, foo and bar are dependant (only one thread at the same time), while normal can be called independently.
but After thread A enter the bar method and synchronize the instance by synchronized(this), Can any thread call the normal method?
It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.
If you are trying to call other methods which aren't synchronized, then it is possible.
after thread A enter the critical section which is synchronized(StaticMyClass.class) or fooStatic method, can any thread call normalStatic?
I think, call fooStatic and normalStatic can be called independently, but barStatic and normalStatic can't. if it is wrong why?
The other methods which are not synchronized can be called independently, but when you call the barStatic() it is not possible for the other methods to be called, as you are synchronizing the entire class. other threads, have to wait until the current thread is finished executing.
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Your latest edit is unclear. You ask a question about
synchronized(myClassInstance)
which doesn't appear anywhere. You ask about locking onmy.normal()
and I have already explained that there is no locking in thenormal
method. (None. Zero. Nada. Nyet ...). Even/* isn't this same as above synchronized(my)? */
doesn't make sense, because your code in this example doesn't show a call tobar()
.– Stephen C
Sep 2 at 2:47