java - 线程如何知道如何 "go back"到先前锁定的 block ?

标签 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));
    }
}

现在假设创建了 2 个线程,并且都简单地在其 run() 中调用 process() 方法。

假设当线程 2 尝试访问 methodA() 时,锁已被线程 1 占用。据我了解,thread2 将跳过同步锁,退出 methodA() 并启动 methodB (这就是拥有超过 1 个锁对象的要点)。但我的问题是,thread2 如何知道“返回”并完成 methodA(),而不是仅仅继续 for 循环?

我知道是这种情况,因为 list1list2 末尾都有 2000 个 Integers,这意味着两个线程都成功完成process() 中的 for 循环各 1000 次,并且每次都调用这两个方法。

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

最佳答案

From what I understood, thread2 will then skip the synchronized lock, exit methodA(), and start methodB

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

关于java - 线程如何知道如何 "go back"到先前锁定的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26344617/

相关文章:

java - Spring mvc - 在方法内部使用 modelAttribute 而不是方法参数作为注释

java - CAS 4.0 LDAP 不会查询服务器

java - LambdaMetaFactory 和私有(private)方法

arrays - Swift 可变数组线程安全

android - Android Studio-Gradle同步失败

c++ - C++ 对 int 的读写是原子的吗?

java - 对同一类应用不同的 equals

Java "unstopped "执行/完成线程

java - 同时运行多个线程

mysql - 在两个不同的数据库之间同步数据