java - 执行在同步块(synchronized block)之间卡住

标签 java multithreading

我有这段代码:

Profile a = randomProfile();
Thread workerA = new Thread(new Downloader(a));
workerA.start();        

Profile b = randomProfile();
Thread workerB = new Thread(new Downloader(b));
workerB.start();

synchronized (workerA) {
    try {
        workerA.wait();
    } catch (InterruptedException e) {
        System.out.println("Error on background thread!");
        System.exit(1);
    }
}

synchronized (workerB) {
    try {
        workerB.wait();
    } catch (InterruptedException e) {
        System.out.println("Error on background thread!");          
        System.exit(1);
    }
}

还有一个实现 Runnable 接口(interface)的 Downloader 类,其 run() 方法如下所示:

@Override
public void run() {     
    synchronized (this) {
        //work...
        notify();
    }
}

现在,有时这会按预期工作。但大多数时候,它似乎卡在第二个同步块(synchronized block)中(它总是通过第一个同步块(synchronized block))。

我做错了什么吗?

我还有一些概念错误,例如与单线程相比,这个实现没有给我带来任何优势吗?

最佳答案

wait()Thread 对象上调用,但 notify()Downloader 上调用> 对象。

因此,后台线程应该毫无问题地运行(尽管完全不同步),并且主线程应该始终在第一个synchronized block 中无限阻塞,因为没有人可以唤醒它。

这种情况的特殊之处在于,您在 Thread 对象本身上调用了 wait(),这是不鼓励的(我的真正意思是:禁止)。当线程终止时,它会自行调用 notifyAll(),因此当 workerA 完成时,您将退出第一个 synchronized block 。但当到达第二个 synchronized block 时,workerB 已经完成,因此第二个 wait() 将永远不会结束。

是否存在概念错误取决于您想要实现的目标。从代码来看,它看起来非常像您尝试做的事情是 join()后台线程。

关于java - 执行在同步块(synchronized block)之间卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26876347/

相关文章:

python - 线程瓶应用程序

c# - 在 C# 中启动外部应用程序时是否使用线程

C++ WxWidgets : Redirecting Stdout to a wxTextCtrl across mulitple threads

java - Java 中 XSD 验证错误消息的 I18n

Java 程序无法在 Solaris 上使用 ftp。

java - List<Dog> 是 List<Animal> 的子类吗?为什么 Java 泛型不是隐式多态的?

java - 设计决策 : should I provide a thread-safety version for all low-level library?

java - 在 JPA 中处理 ID 表的最佳解决方案是什么?

java - 在 JFrame 中获取输入焦点时遇到问题

c++ - Visual Studio 中的内存泄漏