概述
消息有兩種接收方式:同步接收和異步接收。
同步接收:主線程阻塞式等待下一個消息的到來,可以設置timeout,超時則返回null。
異步接收:主線程設置MessageListener,然后繼續做自己的事,子線程負責監聽。
接收方式
同步接收又稱為阻塞式接收;異步接收又稱為事件驅動的接收。
API
同步接收,
是在獲取MessageConsumer實例之后,調用以下的API:
- receive():Message
獲取下一個消息。這個調用將導致無限期的阻塞,直到有新的消息產生。 - receive(long timeout):Message
獲取下一個消息。這個調用可能導致一段時間的阻塞,直到超時或者有新的消息產生。超時則返回null。 - receiveNoWait():Message
獲取下一個消息。這個調用不會導致阻塞,如果沒有下一個消息,直接返回null。
異步接收,是在獲取MessageConsumer實例之后,調用下面的API:
- setMessageListener(MessageListener):void
設置消息監聽器
MessageListener是一個接口,只定義了一個方法:
- onMessage(Message message):void
這是一個回調方法,當有新的消息產生,這個方法會被自動調用。
所以,為實現異步接收,只需要對MessageListener進行實現,然后設置為consumer實例的messageListener。
核心代碼
同步接收和異步接收,
不同的地方在於創建Consumer之后的處理:
同步接收/阻塞式接收 |
1 long timeout = 10 * 1000; 2 for (Message message = consumer.receive(timeout); message != null; message = consumer 3 .receive(timeout)) { 4 String text = ((TextMessage) message).getText(); 5 System.out.println(String.format("receive a message:%s", text)); 6 }
|
異步接收/事件驅動接收 |
1 consumer.setMessageListener(new MessageListener() { 2 public void onMessage(Message message) { 3 try { 4 String text = ((TextMessage) message).getText(); 5 System.out.println(text); 6 } catch (JMSException e) { 7 e.printStackTrace(); 8 } 9 } 10 });
|
暫停退出
不過異步接收還有另外一個問題需要考慮:因為主線程開啟了一個子線程進行監聽,所以主線程可以繼續往下走,但是如果代碼執行完畢,主線程結束,子線程也會結束,也就無法監聽了。所以要想個辦法讓主線程在退出之前暫停。
可以在釋放資源並退出之前,調用下面的方法:
1 /** 2 * 等待用戶輸入.<br> 3 * 用於阻礙程序立即退出,以等待監聽事件的到來. 4 */ 5 private static String waitInput() { 6 @SuppressWarnings("resource") 7 java.util.Scanner scanner = new java.util.Scanner(System.in); 8 System.out.println("按Enter鍵退出:"); 9 String next = scanner.nextLine(); 10 return next; 11 }
如果你想看完整的異步接收的代碼:
AsynConsumer.java