簡體   English   中英

如何在Java中監視異步請求

[英]How to monitor Asynchronous requests in Java

我有2節課。 一個(A)收集一些數據,另一個(B)將數據發送到TCP / IP客戶端。 該過程是異步的,刷新率從接近零到幾秒。 請注意,此應用程序沒有GUI,因此我將無法使用許多內置的“onChange”偵聽器。

在正常情況下,我只需編寫代碼,以便A在B上調用“發送”方法,傳遞數據,這里沒有問題。

現在,假設速率A收集數據是關鍵的(實時)並且A不能等待B完成發送過程(注意B使用TCP,而不是UDP)。 我實現這個的方式是

  • A將數據放在B中的字段中
  • B有一個連續的循環,檢查數據是新的還是現在的。 如果是新的,它會將其發送出去。

如果在發送過程中數據更新了幾次並不重要,只要它不會減慢速度A.為每次發送生成一個新線程原則上不會減慢A但是它可能會導致一團糟。

您可以看到B正在以同步模式工作(但A不是),並且使用帶有Thread.sleep()調用的while循環實現它。 我的問題是:

  1. 我應該使用計時器任務而不是while循環嗎? 我知道大多數人討厭Thread.sleep()調用,但最終我唯一感興趣的是保持CPU低。

  2. 是不是比同步方法更優雅? 在某些情況下,A的數據刷新大約是1秒,如果我能有一個能夠對事件起作用的監聽器,那將是很好的。 在這種情況下,25ms的睡眠時間將浪費周期。 在其他情況下,它非常快,我根本不想睡覺。

* 示例:假設A正在從您的屏幕提交屏幕截圖,B正在將它們發送給客戶端。 只有最后一個很重要,B會盡可能快地走*

任何想法或建議? 請盡量保持簡單和低CPU

非常感謝!

我會在AB之間設置一個LinkedBlockingQueue ,當隊列變滿時,它的大小不應該阻塞A A ,收集數據的方法會將其發布到隊列中。 B ,只要隊列中有一個項目,它就是新的,應該被發送出去。

如果您希望B利用AA消息的多次編輯進行合並並作為單個更新發送,那么我會使用Observer

  1. A不斷更新的消息是Observable
  2. B是此消息的觀察者。
  3. 每次A更新消息時,都表示B采取某些行動。
  4. B可以選擇立即將更新發送給客戶端
  5. B還可以選擇使用定時器等待一段時間,並僅在定時器觸發后才將更新發送給客戶端。 發送更新的代碼將是TimerTask。
  6. A更改消息之前, B不會再次設置定時器。

我會這樣做:

A以適當的方式收集數據,然后發送“下一條消息”發送。 如果已有消息待處理,請讓新消息替換/更新先前的消息。

B檢查ay掛起的消息,如果有消息,它會抓取它並將其發送給客戶端。 但是,如果沒有待處理的消息,則B等待一個消息可用。

Object lock = new Object();
Object pending = null;

public void post(Object message) {
    synchronized (lock) {
        pending = message;
        lock.notifyAll();
    }
}

public Object getNextMessage() {
    Object message;
    synchronized (lock) {
        while (pending == null) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                // Ignore
            }
        }
        message = pending;
        pending = null;
    }
    return message;
}

使用隊列,你可以做

BlockingDeque<Object> queue = new LinkedBlockingDeque<Object>(1);

public void postMessage(Object message) {
    // If previous message is still pending we replace it.
    queue.clear();
    queue.offer(message);
}

public Object getNextMessage() {
    while (true) {
        try {
            return queue.take();
        } catch (InterruptedException e) {
            // Ignore interrupts
        }
    }
}

當然,在這兩個例子中,代替while(true)使用信號是好的,這樣你就可以優雅地關閉。

您可以使用Exchanger

B將發送信息,使用交換機進行交換(他可能會等待A及其罰款)
交換完成后,他將發送信息。

A將使用超時0的交換器,這意味着如果B還沒有等待,那么我們跳過這個交換,如果他等待交換,A將繼續他的工作,B現在可以發送信息。

B忙時出現的信息將被忽略(A中的超時0交換只會在B忙時拋出異常,請確保抓住它)

最優雅的方式是使用消息隊列 A一旦可用就將數據寫入隊列。 B訂閱隊列,並在新數據進入時通知。消息隊列為您處理所有事務。

但是,您應該更明確:是否應該通知B每條消息? 如果更新丟失會發生什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM