如何使用等待和通知

时间:2015-08-30 06:05:37

标签: java multithreading wait notify

我正在创建一个java应用程序,我在其中使用三个线程同时对文本文件执行三个操作。当我点击开始时我的应用程序中有一个切换按钮我正在调用一个方法调用()创建和启动所有这些线程,当我点击停止我正在调用一个新方法stopcall(),其中我写了一个代码来停止所有这些线程。

public void stopcall() throws Exception {
    System.out.println("hello stop call");

    synchronized(t) {   
        t.wait();   
    }

    synchronized(t1) {  
        t1.wait();
    }

    synchronized(t2) {  
        t2.wait(); 
    }

}

但是当我调用这个方法我的应用程序被挂起时,stopcall()方法无法正常工作。如果有人帮助我并告诉我如何在我的应用程序中使用wait和notify,我将不胜感激

3 个答案:

答案 0 :(得分:1)

您的应用程序挂起,因为您正在等待锁定的对象。 wait()方法挂起线程,直到另一个线程对该对象使用notify()。

答案 1 :(得分:1)

您必须同步访问共享对象(在本例中为文件)的方法以启用安全线程。这是一个使用布尔标志来指示资源当前是否正在使用的示例。

如果在使用中,下一个线程将调用wait()并等待通知。

同时当前正在使用'线程将完成synchronized块 - 它将调用notifyAll()以警告所有等待的线程资源是空闲的。

public class TestSync {
private boolean fileInUse = false;

public synchronized void syncWriting() {
    // blocks until a the file is free. if not - the thread will 'wait'. 
    // when notified : will do the while-loop again
    while (true) {
        if (!fileInUse){
            System.out.println("using the free file");
            fileInUse = true;
            //
            // code to write and close the file
            //
            notifyAll();
            return;
        }
        try {
            // wait if file in use. after being notified : 
            wait();
        } catch (InterruptedException e) {e.getMessage();}
    }
}

答案 2 :(得分:0)

wait() / notify() / notifyAll()方法相当容易理解。

foo.wait()释放foo上的锁,然后它会一直休眠,直到通知foo,然后在它返回之前重新获取锁。

foo.notifyAll()唤醒所有正在foo.wait()次呼叫中休眠的线程。如果没有线程在被调用时正在休眠,那么它根本不会做任何事情。

foo.notify()foo.notifyAll()相同,只是它只选择一个睡眠线程(如果有的话)并唤醒它。

使用wait()notify()的技巧是,假设您希望某个线程A用foo.notify()唤醒线程B.在主题A调用foo.wait()之前,你如何保证线程B已经在foo.notify()调用中休眠?

记住:如果首先发生通知,那么它将“丢失”。也就是说,通知将什么也不做,等待将永远不会返回。

这让我们知道为什么只允许从synchronized(foo)块内部调用foo.wait()和foo.notify()。您应该使用同步和一些共享变量来阻止线程A等待()已经发生的通知。