同步块上的线程执行顺序

时间:2013-06-29 18:28:58

标签: java multithreading

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

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

1 个答案:

答案 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()