为什么线程无法进入无限时间的等待状态?

时间:2013-09-14 18:30:53

标签: java multithreading

下面是我在本地计算机上运行时成功完成执行的代码段。

我无法理解为什么这个线程不会进入无限等待状态?

public class Job extends Thread {

    private int counter;

    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 100000; i++) {
                counter++;
            }

            this.notifyAll();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Job job = new Job();
        job.start();
        synchronized (job) {
            job.wait();
        }

        System.out.println(job.counter);
    }
}

是否有任何保证,上述代码将始终在每种情况下完成执行?任何人都可以澄清一下吗?

4 个答案:

答案 0 :(得分:1)

看起来你手上有Race Condition - 这完全取决于首先发生的synchronized(job) - 主线程中的那个或工作中的那个。

答案 1 :(得分:0)

有几种可能性

  1. 主线程首先进入synchronizedwait()。在这种情况下,程序将终止,因为job Thread会在notify()对象上调用synchronized
  2. job Thread首先进入synchronized阻止,并在主notify()来电Thread之前致电wait(),即。{ main Thread不能,因为它在synchronized块等待。这将阻止该应用程序,因为主Thread将无法从wait()电话返回。

答案 2 :(得分:0)

  

我无法理解为什么这个线程不会进入无限等待   状态?

如果在this.notifyAll()之前调用job.wait(),就会发生这种情况。

添加一个标志以测试完成,如下所示:

public class Job extends Thread {

    private int counter;
    private boolean finished = false;

    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 100000; i++) {
                counter++;
            }

            finished = true;
            this.notifyAll();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Job job = new Job();
        job.start();
        synchronized (job) {
            while (!job.finished)
                job.wait();
        }

        System.out.println(job.counter);
    }
}

这样你就可以保证程序不会遇到竞争条件而且会永远等待。另请注意,您现在受到spurious wakeups的保护。

答案 3 :(得分:0)

除了虚假的唤醒问题(大多数情况下不应该影响这种简单的使用),你应该期望代码总是完成。

您似乎缺少的一件事是job.wait();释放锁定,允许执行另一个synchronized块并调用notifyAll()。此时,wait醒来,主要方法退出。