java-从线程中通知一个线程

时间:2015-01-22 12:23:13

标签: java multithreading notify

我尝试实现线程wait()和notify(),但是notify方法不起作用,你能帮帮我吗? 我希望读者线程尝试从他的消息框中读取;如果消息框为空,则读者等待作者完成作业。但在通知行动之后,读者仍然等待并且什么也不做,作者继续他的工作。 这是我的代码(其他自定义对象工作正常):

    public class TrheadTEST {
    private static class AgentThred implements Runnable {    
        private final  String name;
        private final String category;
        private final PersonalAgentID agentID; // it has name and category 
        private AgentThred obiettivo; 
        private Thread trd; // i try to call notify for a specific thread.
        public MessageBox msgx; // each thread has a messagebox. Agent can read only her own messagebox        
        public AgentThred(String nam, String cat){
            this.name = nam;
            this.category = cat;
            this.agentID = new PersonalAgentID(this.name, this.category);
            this.msgx.setOwner(this.agentID);            
            this.msgx = new MessageBox();
        }
        public void setObj(AgentThred i) {
            this.obiettivo = i;
        }
        public void setThread(Thread i) {
            this.trd = i;
        }
        @Override
        synchronized  public void run() { 
        {
//set a message to send

        if(this.name == "Mercoledi"){
            while(true){
                // writer write a message in reader messagebox
                System.out.println("writer wrote");
                notifyAll();   //wake up the reader--doesn't work
               //sleep(500)
            }
        }
        else
            while(true){
                if(this.msgx.imEmpty()){ // if reader messagebox is empty
                    System.out.println("reader can't read");
                    wait(); //wait until writer put a message in the reader message box
                }
                else{
                    System.out.println("reader can read ");
                    //read the message
                }
            }
    }
}
}
}
public static void main() {
    AgentThred agt1 = null;
    AgentThred agt2 = null;
     MessageBox msg = new MessageBox();
    }
    agt1 = new AgentThred("Mercoledi","Addams");
    agt2 = new AgentThred("Mano","Addams");
    Thread t1 = new Thread(agt1);
    Thread t2 = new Thread(agt2);
    t2.start();
    t1.start();
//I need a join here? 
}
}

3 个答案:

答案 0 :(得分:0)

要从等待中唤醒agt2,您需要在与用于等待的对象相同的对象上调用notifyAll。在您的情况下,agt2等待this.wait(),因此您需要致电agt2.notifyAll()将其唤醒。

另请注意,建议不要将字符串与==进行比较,即使它恰好适用于您的情况。

所以你可以定义一个:

private static final Object waiter = new Object();

并致电:

synchronized(waiter) {
  waiter.wait();
  //or
  waiter.invokeAll();`
}

答案 1 :(得分:0)

您需要在两者之间有一个共同的对象,您可以等待并通知。现在,您正在同步这个两个不同线程的实例,并喋喋不休地说this.waitthis.notify,因此无效。

要等待并通知工作,您需要在同一个对象上获取互斥锁。有关详细信息,请参阅this

wait Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

您可以尝试将公共对象传递给单个线程,例如String,并对其进行同步,并使用该对象调用wait和notify。像:

//thread1
synchronize(myString) {
    myString.wait();
}

//thread2
synchronize(myString) {
    myString.notifyAll();
}

答案 2 :(得分:0)

您正在传递消息,因此请尝试使用java.util.concurrent类。创建两个线程共有的LinkedBlockingQueue,并使用put()和take()方法传递消息。

如果没有可用于读取的消息或没有可用于放置消息的空间,则可以避免使用同步和阻止。如果这不完全符合您的要求,不同的类会给出不同的行为。