如何同时调用阻止函数

时间:2016-06-14 06:51:37

标签: java multithreading function blocking

我有一个A类(),当它到来时会收到消息,然后把它放到地图上。有两种方法:

  1. boolean haveResult(id):返回是否有id
  2. 的结果
  3. String getResult(id):返回id的结果。
  4. 但我不知道消息何时到来,可能是10或30秒。

    Class A implements MessageListener{
    
      private Map<String, JSONObject> resultMap = new HashMap<>();
    
      //receive message and put them to map
      public void onMessage(Message msg) {
         synchronized (this) {
            resultMap.put(msg.getID(),msg.getJson());
         }
      }
    
      public boolean haveResult(String id) {
        synchronized (this) {
            return resultMap.containsKey(id);
        }
       }
    
        public String getResult(String id) {
        synchronized (this) {
            JSONObject obj = resultMap.get(id);
            return obj.toString();
        }
    
      }
     }
    

    现在,我想向服务器发送请求,在服务器处理商务句柄之后,它将调用类A方法:onMessage(msg)。然后我想获得此请求的消息(请求和响应将包含相同的唯一ID)。所以,我写了B级:

    Class B{
    
       function requestData(String id, String requestData){
          //send request to server
          RequestHandle.getInstance().sendRequest(id,requestData);
          while(true){
             if(!A.getInstance().haveResult(id)){
                 Thread.sleep(1*1000);
             }else{
               return A.getInstance().getResult(id);
             }
          }
      }
    }
    

    现在问题是B.requestData(String id, String requestData)将同时被多次调用,但是对于每个调用,它必须等待结果,换句话说,函数requestData()是阻塞函数。例如,在获得结果之前,method1调用requestData()可能需要20秒,同时,method2调用requestData()并且在获得结果之前可能只需要1s,但是现在,method2必须等待method1调用完成,所以方法2需要20 + 1 = 21s,如何解决?

1 个答案:

答案 0 :(得分:0)

您想使用wait / notify:

Class A implements MessageListener{

  private Map<String, JSONObject> resultMap = new HashMap<>();

  //receive message and put them to map
  public void onMessage(Message msg) {
     synchronized (this) {
        resultMap.put(msg.getID(),msg.getJson());
        this.notifyAll();
     }
  }

  public void waitForMessage(String id) {
     synchronized (this) {        
        while(!haveResult(id) {
           try {
              this.wait();
           } catch(InterruptedException e) {}
        }
     }
  }
  ...

}

B类只是调用A.waitForMessage(id),它将阻塞直到消息出现。

如果你不熟悉wait / notify,我建议你阅读这个主题。 Oracle documentation is here但您会通过谷歌找到更多教程。