线程如何知道如何“返回”先前锁定的块?

时间:2014-10-13 16:26:00

标签: java multithreading synchronization

考虑以下代码:(注意:为了代码清晰,删除了所有try / catch)

Object lock1 = new Object();
Object lock2 = new Object();
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();

public void process() {
    for (int i = 0; i < 1000; i++) {
        methodA();
        methodB();
    }
}

public void methodA() {

    synchronized (lock1) {
        Thread.sleep(1); // mimics other operations
        list1.add(random.nextInt(100));
    }
}

public void methodB() {

    synchronized (lock2) {
        Thread.sleep(1); // mimics other operations
        list2.add(random.nextInt(100));
    }
}

现在假设创建了两个线程,并且只是在process()中调用run()方法。

假设当thread2尝试访问methodA()时,thread1已经锁定了。根据我的理解,thread2将跳过同步锁定,退出methodA(),然后启动methodB(这是拥有多个锁定对象的点)。但我的问题是如何将thread2知道&#34;返回&#34;并完成methodA(),而不只是继续for循环?

我知道情况就是这样,因为list1list2最后都有2000 Integers,这意味着两个线程都成功完成了for循环{ {1}}每次1000次,每次都调用两种方法。

我唯一的猜测是,当线程遇到被锁定的同步块时,它会将该块存储在队列(或其堆栈?)中并继续运行,直到该块再次空闲。

2 个答案:

答案 0 :(得分:6)

  

根据我的理解,thread2将跳过同步锁定,退出methodA(),然后启动methodB

不,thread2会阻止,即。停止执行,直到另一个线程完成methodA并释放锁定。然后它将恢复执行,获取锁定并执行该方法。

答案 1 :(得分:0)

方法()和方法()被顺序调用,所以如果在methodA()中存在锁定,除非锁定被清除,否则线程将处于阻塞状态。