Reputation: 53481
I have a method shout() with a synchronized block.
private void shout(){
System.out.println("SHOUT " + Thread.currentThread().getName());
synchronized(this){
System.out.println("Synchronized Shout" + Thread.currentThread().getName());
try {
Thread.sleep(50);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Synchronized Shout" + Thread.currentThread().getName());
}
}
If I have two Threads that run this method, am I correct in assuming that the two "Synchronized Shout" will always appear one after the other? There can be no other statements in between the "Synchronized Shout"?
Upvotes: 1
Views: 356
Reputation: 57707
When two or more threads are running against the same instance, then the SHOUT can appear anywhere, because it's outside the synchronized block, and thus unguarded. The "synchronized shout"s will always appear strictly in order, with no synchornized shout from another thread getting in between and affecting the order.
Upvotes: 0
Reputation: 7866
Since the line that prints "SHOUT..." does not require a lock, it can appear at any point. Thus, even if one thread is holding the lock, another thread may come in and print "SHOUT...".
The following code shows the interleaving:
public class Interleave {
public static void main(String[] args) throws Throwable {
Task task = new Task();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
Thread.sleep(25);
t2.start();
}
private static class Task implements Runnable {
public void run() {
shout();
}
private void shout() {
System.out.println("SHOUT " + Thread.currentThread().getName());
synchronized (this) {
System.out.println("Synchronized Shout " + Thread.currentThread().getName());
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Synchronized Shout " + Thread.currentThread().getName());
}
}
}
}
It prints out
SHOUT Thread-0
Synchronized Shout Thread-0
SHOUT Thread-1
Synchronized Shout Thread-0
Synchronized Shout Thread-1
Synchronized Shout Thread-1
Upvotes: 2
Reputation: 147124
So long as the this
reference is the same. If you run the code on two different objects, the lock will have no effect.
Note, if you were to use Object.wait
on this
instead of calling Thread.sleep
to delay, then the lock would be removed (and reacquired before moving on).
Upvotes: 2