Reputation: 55
Suppose we have the following class
class Class1 {
public void Method1() {
synchronized(myobject) {
/* some code */
}
}
}
where myobject is the instance of the class
class myClass {
public void Method2() {
synchronized(someOtherObj) {
/* some code */
}
}
public synchronized void Method3() {
/* some code without synchronized blocks */
}
public void Method4() {
/* some code without synchronized blocks */
}
}
Help me please to understand which code blocks of myobject are made available only for the tread called the method Method1.
Upvotes: 1
Views: 818
Reputation: 14289
You need to know that
void synchronized myfunc()
is short-hand for:
void myfunc() {
synchronized (this) {
}
}
where this
is the current instance of the class called from outside.
So if you have the following setup:
final MyClass a = new MyClass();
// Thread 1:
a.myfunc();
// Thread 2:
a.myfunc();
Then both threads will wait on the same object (which is the instance a).
However in the following setup:
final MyClass a = new MyClass();
final MyClass b = new MyClass();
// Thread 1:
a.myfunc();
// Thread 2:
b.myfunc();
Both threads can access myfunc
at the same time, because they synchronize on different objects (instance a for thread 1 and instance b for thread 2).
If you would write the code in the following way:
final Object a = new Object();
final Object b = new Object();
static void myfunc() {}
// Thread 1:
synchronized(a) {
myfunc();
}
// Thread 2:
synchronized(b) {
myfunc();
}
It would be the exact same thing (considering blocking), because - as above - a synchronized method is just a short-hand expression for synchronized(this)
.
Upvotes: 0
Reputation: 31648
Help me please to understand which code blocks of myobject are made available only for the tread called the method Method1.
I think you have synchronization backwards. No other thread can execute the block inside of Class1#Method1()
unless it is holding the myobject
"lock". The actual methods of myClass
are unaffected. Any methods from any threads can invoke methods of myobject
if they have a reference to it. (Since the methods in myClass
are also synchronized, they may also block but that is a separate issue.)
For that reason, it is important to always make the object you are locking on private and not publish the reference by returning it in any public method.
Upvotes: 0
Reputation: 351
There are two ways to synchronize something. You can make a method synchronized:
public synchronized void doSomething() {
// safe to do stuff
}
or you can synchronize on an object:
synchronize( object ) {
// safe to do stuff
}
In your example, Class1.Method1 and myClass.Method3 and myClass.Method4 will all block each other. myClass.Method2 is locking someOtherObject which doesn't affect anything in the example.
What can be confussing is when you add the synchronized keyword to a method, it is really just locking the 'this' reference.
public synchronized void method() { }
is the same as:
public void method() {
synchronized( this ) {
// this may help clarify
}
}
That is all you get. When the object are synchronized, they cannot be accessed by any other objects in any other threads. This stuff can be difficult to get right. I recommend the following book:
Java Concurrency in Practice by Brian Goetz et al. Link: http://amzn.com/0321349601
Upvotes: 1