java - 尝试理解同步方法

标签 java multithreading

对于下面的代码,预期输出是:

Waiting for b to complete...
Total is: 4950

为什么它无法打印 Total is.. first then Waiting for b.. 之后?我认为在某些情况下可以首先执行b.start(),然后它用持有ThreadB的锁ThreadB.run()中的synchronized(this)从而阻止main进入synchronized(b)

我刚才说的有什么问题吗?

public class ThreadA {
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();

        synchronized(b) {
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Total is: " + b.total);
        }
    }
}

class ThreadB extends Thread {
    int total;
    @Override
    public void run() {
        synchronized(this) {
            for(int i=0; i<100 ; i++) {
                total += i;
            }
            notify();
        }
    }
}

最佳答案

两个输出语句始终具有相同的顺序,因为它们在一个线程上执行。等待它们之间的另一个线程完成不会改变它们的执行顺序。

如果将“Total is ...”输出放在 b 的 run() 末尾,那么可能有机会看到输出的不确定顺序。

编辑 - 另请注意 @Holger 对此答案的评论:

[...] in the unlikely, but still possible case that ThreadB’s synchronized block is executed first, its notify() call will have no effect as no-one is waiting yet and then, ThreadA’s wait() call may hang forever as there will be no subsequent notification.

关于java - 尝试理解同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30931350/

相关文章:

c# - 无法从非 UI 线程显示 FolderBrowserDialog 吗?

Android N 中使用 jsoup 下载数据时出现 java.lang.VerifyError

java - fragment -E/RecyclerView : No adapter attached; skipping layout

c# - 退出没有循环的线程

Android SQLite 查询导致许多跳帧

java - 通知时获取非法监视器状态异常

java - 为什么使用线程时我的程序变慢?

Java:嵌套列表的返回类型

java - 删除重复项方法不会删除重复项

java - 如果所有元素 xpath 都相同,如何区分元素