执行在同步块之间卡住

时间:2014-11-11 23:10:23

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

实现Downloader接口的Runnable类及其run()方法如下所示:

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

现在,这有时是有意的。大多数情况下,它似乎陷入第二个同步块(它总是通过第一个)。

我做错了吗?

我也有一些概念错误,例如:这个实现没有给我任何优势超过一个线程?

1 个答案:

答案 0 :(得分:2)

wait()个对象上调用Thread,但在notify()个对象上调用Downloader

因此后台线程应该没有问题地运行(虽然完全不同步),并且主线程应该总是在第一个synchronized块中阻塞到无穷大,因为没有人将其唤醒。

这个案例很特别的地方是你在wait()对象本身上调用了Thread,这是不鼓励的(而且我的意思是:禁止)。当一个线程终止时,它会自己调用notifyAll(),所以当workerA完成后,你就会离开第一个synchronized块。但到达第二个synchronized块时,workerB已经完成,因此第二个wait()将永远不会结束。

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