1

在下面的代码中,我试图找出线程处理同步块上的执行:

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 才能进入同步块。

4

1 回答 1

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()
于 2013-06-29T18:31:06.727 回答