Java是否隐式通知等待线程? [英] Does Java notify waiting threads implicitly?

查看:146
本文介绍了Java是否隐式通知等待线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个应该永远不会停止的测试应用。它发出 t.wait() t 是一个线程对象),但我从不打电话通知。为什么这段代码会结束?
尽管主线程在 t 上同步,但生成的线程会运行,因此它不会锁定此对象。

I wrote a test app that should never stop. It issues t.wait() (t is a Thread object), but I never call notify. Why does this code end? Despite the main thread synchronizing on t, the spawned thread runs, so it doesn't lock this object.

public class ThreadWait {
    public static void main(String sArgs[]) throws InterruptedException {
        System.out.println("hello");
        Thread t = new MyThread();
        synchronized (t) {
            t.start();
            Thread.sleep(5000);
            t.wait();
            java.lang.System.out.println("main done");
        }
    }
}

class MyThread extends Thread {
    public void run() {
        for (int i = 1; i <= 5; i++) {
            java.lang.System.out.println("" + i);
            try {
                Thread.sleep(500);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

结果是主线程等待5秒,在此期间工作人员给出其输出。然后在5秒钟结束后,程序退出。 t.wait()不等待。如果主线程不会休眠5秒(注释这一行),那么 t.wait()实际上会等到工作人员完成。当然, join()是一种在这里使用的方法,但是,出乎意料的是, wait()做同样的事情as join()。为什么?

The result is that the main thread waits 5 seconds and during this time worker gives its output. Then after 5 seconds are finished, the program exits. t.wait() does not wait. If the main thread wouldn't sleep for 5 seconds (commenting this line), then t.wait() would actually wait until the worker finishes. Of course, join() is a method to use here, but, unexpectedly, wait() does the same thing as join(). Why?

也许JVM看到了,因为只有一个线程正在运行,所以没有机会通知主线程并解决死锁问题。如果这是真的,它是一个记录的功能吗?

Maybe the JVM sees that, since only one thread is running, there is no chance to notify the main thread and solves the deadlock. If this is true, is it a documented feature?

我在Windows XP,Java 6上进行测试。

I'm testing on Windows XP, Java 6.

推荐答案

您正在等待线程 - 并且大多数对象未被隐式通知,线程终止时通知线程对象。它记录在某处(我正在寻找它......)你使用等待 / 通知 on Thread 对象,就像在内部完成的那样。

You're waiting on a Thread - and while most objects aren't implicitly notified, a Thread object is notified when the thread terminates. It's documented somewhere (I'm looking for it...) that you should not use wait/notify on Thread objects, as that's done internally.

这是一个很好的例子,为什么它是使用私有对象进行同步(以及等待/通知)的最佳做法 - 您的代码只知道 的内容。我通常使用类似的东西:

This is a good example of why it's best practice to use a "private" object for synchronization (and wait/notify) - something which only your code knows about. I usually use something like:

private final Object lock = new Object();

(但是,一般来说,使用java提供的一些更高级别的抽象更清晰。 util.concurrent如果可以的话。如评论中所述,实现 Runnable 而不是扩展 Thread 也是一个好主意。你自己。)

(In general, however, it's cleaner to use some of the higher-level abstractions provided by java.util.concurrent if you can. As noted in comments, it's also a good idea to implement Runnable rather than extending Thread yourself.)

这篇关于Java是否隐式通知等待线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆