在下面的代码中,我试图找出线程处理同步块上的执行:
public class ThreadExp {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r, "Thread1");
Thread t2 = new Thread(r, "Thread2");
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
callFn();
}
private void callFn() {
System.out.println(Thread.currentThread().getName() + ": entered callSync()");
synchronized (Thread.currentThread()) {
System.out.println(Thread.currentThread().getName() + ": inside sync");
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " leaving sync");
}
System.out.println(Thread.currentThread().getName() + ": leaving callSync()");
}
}
实际输出:
Thread1: entered callFn()
Thread2: entered callFn()
Thread1: inside sync block
Thread2: inside sync block
// 5000 millisec sleep
Thread2 leaving sync block
Thread1 leaving sync block
Thread2: leaving callFn()
Thread1: leaving callFn()
我期待的是:
Thread1: entered callFn()
Thread2: entered callFn()
Thread1: inside sync block
// 5000 millisec sleep
Thread1 leaving sync block
Thread1: leaving callFn()
Thread2: inside sync block
Thread2 leaving sync block
Thread2: leaving callFn()
总体而言,我认为Thread1将获得锁定然后进入睡眠状态。只有在Thread1完成后,Thread2才能进入同步块。
答案 0 :(得分:5)
您正在同步线程本身:
synchronized (Thread.currentThread())
所以每个线程都有自己的锁,他们可以同时执行synchronized
块。
如果您希望synchronized
块一次只能由一个线程运行,则需要使用相同的锁。
在您的示例中,它可能只是this
,因为Runnable
实例对于您的两个线程是相同的:
synchronized(this) {...}
输出将如下所示:
Thread1: entered callSync()
Thread1: inside sync
Thread2: entered callSync()
Thread1 leaving sync
Thread1: leaving callSync()
Thread2: inside sync
Thread2 leaving sync
Thread2: leaving callSync()