有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java从线程通知线程

我尝试实现threadwait()和notify(),但notify方法不起作用,您能帮我吗? 我希望读者线程尝试读取他的消息框;如果messagebox为空,则读卡器将等待,直到编写器完成工作。但在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) 个答案

  1. # 1 楼答案

    在这两个对象之间需要一个公共对象,您可以在该对象上等待并通知。现在,您正在同步两个不同线程的实例,并尝试说this.waitthis.notify,因此它不起作用

    要使wait和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.
    

    您可以尝试将一个公共对象传递给单个线程(比如字符串),并在同一线程上进行同步,然后使用该对象调用wait和notify。比如:

    //thread1
    synchronize(myString) {
        myString.wait();
    }
    
    //thread2
    synchronize(myString) {
        myString.notifyAll();
    }
    
  2. # 2 楼答案

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

    这避免了在没有消息可读取或没有空间可放置消息时使用同步和块。如果这不是您所需要的,那么不同的类会给出不同的行为

  3. # 3 楼答案

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

    还要注意,即使字符串与==恰好在您的情况下起作用,也不建议将其进行比较

    因此,您可以定义:

    private static final Object waiter = new Object();
    

    并致电:

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