簡體   English   中英

Java-在使用者正在等待並且tomcat關閉時停止線程

[英]Java - Stop thread while consumer is waiting and tomcat is shutdown

我有一個servlet,它是一個單例。

在初始化中,我創建了生產者和消費者。

consumer = new MyThread();
consumer.start();

運行的方法是這樣的:

@Override
public void run() {
    while (!isShutdown()) {
        if (queue.isEmpty())
            queue.wait();
        else
            ...
    }
}

然后我有銷毀方法。 將shutdown設置為true,我使用.join

        consumer.setShutdown(true); 
        consumer.join();

但是方法.join獲得了鎖定..並沒有完成。 如果我將queue.wait更改為Thread.sleep(),它可以工作...但是我不想更改...我做錯了什么?

如果我沒有完成線程,那么我得到了:嚴重:Web應用程序[/ test]似乎已經啟動了一個名為[Comsumer0]的線程,但是未能停止它。 這很可能造成內存泄漏。

隊列很可能是空的,並且由於您已關閉,因此您絕不會將任何東西發送到隊列中以使其醒來。

通過在設置關閉標志后向隊列發送虛擬消息或僅完全刪除關閉標志並向隊列發送關閉命令來解決此問題。

還應注意,如果您的關閉標志不是volatile (或AtomicBoolean ),則由於CPU內部的緩存,一個線程可能看不到另一個線程正在設置它。

這是BlockingQueue的用途:

    BlockingQueue queue = new ArrayBlockingQueue(5);
    // ...
    while (!isShutdown()) {
        Object poll = queue.poll(5, TimeUnit.SECONDS);
    }

您應該按照上面的建議更改設計,或者如果您不想更改代碼,請更改setShutdown()方法主體和語句以通知隊列。

public void setShutdown(boolean shutdown) {
  this.shutdown = shutdown;
  this.queue.notifyAll();
}

使用等待/通知方法是創建使用者-生產者模式的舊方法。

最好使用BlockingQueue。

BlockingQueue.put() -用於生產者,而BlockingQueue.poll() -用於消費者。

BlockingQueue將Waiting方法隱藏在BlockingQueue.pollBlockingQueue.put ,並將阻塞Consumer線程,直到Producer向隊列添加值為止。

要修復上面的示例,您應該使它等待有限的時間,例如queue.wait(1000) ,或者喚醒顯式調用queue.notify()使用者線程。

暫無
暫無

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

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