2016-06-14 10 views
0

У меня есть класс А(), который будет получать сообщения, когда он приходит, а затем положить его на карту .it есть два метода:как Вызов функции блокировки одновременно

  1. boolean haveResult(id): вернуться ли есть результат для id
  2. String getResult(id): вернуть результат для id.

Но я не знаю, когда придет сообщение, возможно, 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(); 
    } 

    } 
} 

Теперь я хочу, чтобы отправить запрос на сервер, после BUSSINESS ручки сервера ручки, он будет вызывать класс метод: OnMessage (МСГ). то я хочу получить сообщение для этого запроса (requst и response будут содержать тот же уникальный идентификатор). так, я пишу класс 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() является блокирование функция. например, метод1 вызовет requestData(), возможно, потребуется 20 секунд, прежде чем получить результат, в то же время метод method2 вызовет requestData(), и, возможно, ему просто нужно 1 с до получения результата, но на данный момент метод2 должен ждать завершения метода method1, поэтому для метода2 нужно 20 + 1 = 21s, как его решить?

+0

Это очень неясно. Являются ли классы 'A' и' B' в одном JVM или 'A' на сервере и' B' на клиенте? –

+0

Возможно, вы захотите рассмотреть совершенно другой дизайн. Например, посмотрите на https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html –

+0

Класс A и класс B все в клиенте, фактически класс MessageListenr запускается в новый поток. – Yang

ответ

0

Вы хотите использовать ожидание/уведомить:

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), которые будут блокировать, пока сообщение не появляется.

Если вы не знакомы с ожиданием/уведомлением, я предлагаю вам ознакомиться с темой. Oracle documentation is here, но вы найдете еще много обучающих программ через google.