1

HI 编写了一个示例程序,用于测试 java 中的等待行为。

我的 Runnable 实现:

class ThreadWait implements Runnable {
    Object lock = new Object();
    ThreadWait(Object lock){
        this.lock = lock;
    }
    @Override
    public void run() {
        try {
            synchronized (lock){
                System.out.println("Started : "+Thread.currentThread().getName());
                wait();
                System.out.println("Completed : "+Thread.currentThread().getName());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在我main喜欢的范围内使用:

Object lock = new Object();
ThreadWait t1 = new ThreadWait(lock);
ThreadWait t2 = new ThreadWait(lock);
Thread a= new Thread(t1);
a.setName("A");
Thread b= new Thread(t2);
b.setName("B");
a.start();
b.start();

运行此程序时,我收到此异常:

Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException
Started : A
    at java.lang.Object.wait(Native Method)
Started : B
    at java.lang.Object.wait(Object.java:502)
    at ThreadWait.run(SynchronizedExample.java:34)
    at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at ThreadWait.run(SynchronizedExample.java:34)
    at java.lang.Thread.run(Thread.java:745)
4

1 回答 1

6

你的问题是你同步了lock,但你正在等待(特别是:包含等待调用的Runnablethis实例)。

您只能对您拥有监视器的对象调用 wait 。您的代码拥有lock,但不是this

所以你应该等待锁定对象。但请注意:那么您的代码将死锁!

这导致了建议:您应该多研究“理论”。您会看到,可以使用等待/通知来“同步”应该处理相同数据的不同线程;但这不是您通过反复试验(有效地)学习的东西;因为有太多微妙的细节会影响试错实验的结果。您可能会从这里那里开始阅读。

最后一句话:同样重要的是要理解,是的,等待/通知是重要的概念;但你很少在“现实世界”中使用它们。这些都是非常底层的机制,Java 在它们之上添加了更强大的抽象。

于 2017-05-02T05:16:49.800 回答