我有一个带有synchronized块的方法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());
}
}
如果我有两个运行此方法的线程,我是否正确假设两个“同步喊”将始终一个接一个出现? “同步喊”中没有其他陈述?
答案 0 :(得分:2)
只要this
引用相同即可。如果在两个不同的对象上运行代码,则锁定将无效。
注意,如果您在Object.wait
上使用this
而不是调用Thread.sleep
来延迟,那么锁定将被删除(并在继续之前重新获取)。
答案 1 :(得分:2)
由于打印“SHOUT ...”的行不需要锁定,因此它可以随时出现。因此,即使一个线程持有锁,另一个线程可能会进入并打印“SHOUT ...”。
以下代码显示了交错:
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());
}
}
}
}
打印出来
SHOUT Thread-0
Synchronized Shout Thread-0
SHOUT Thread-1
Synchronized Shout Thread-0
Synchronized Shout Thread-1
Synchronized Shout Thread-1
答案 2 :(得分:0)
当两个或多个线程针对同一个实例运行时,SHOUT可以出现在任何地方,因为它在同步块之外,因此无人看守。 “同步喊叫”将始终严格按顺序出现,其他线程之间没有同步的喊叫,并影响订单。