2011-12-20 34 views
3

我有一個多線程應用程序,它可以在運行中創建數百個線程。當JVM的內存少於創建下一個Thread所需的內存時,它無法創建更多線程。每個線程生活1-3分鐘。有沒有辦法,如果我創建一個線程並且不啓動它,應用程序可以在它有資源時自動啓動它,否則等到現有線程死亡?產生大量線程而不會耗盡內存

回答

1

只需編寫代碼即可完成您想要的任務。你的問題描述了一個解決方案的配方,只是實現該配方。此外,你應該認真考慮重新設計。你只需要一個線程來處理你想要做的事情同時,你不能同時做幾百件事情。

2

你負責,如果你正在運行接近你的極限分配更多資源,之前檢查你的可用內存。要做到這一點的方法之一是使用MemoryUsage類,或使用一個:

Runtime.getRuntime().totalMemory() 
Runtime.getRuntime().freeMemory() 

...,看看有多少內存可用。爲了弄清楚有多少是使用,當然,你剛剛從free減去total。然後,在您的應用中,只需設置一個MAX_MEMORY_USAGE值,即當您的應用使用該金額或更多內存時,它會停止創建更多線程,直到已使用內存的金額回落到此閾值以下。這樣,您總是以最大數量的線程運行,並且不會超出可用內存。

最後,而不是試圖不啓動它們(因爲一旦你創建了Thread對象時,你已經在內存佔用)創建線程,只需執行下列操作之一:

  • 保持那需要的東西隊列中進行,併爲那些東西一個新的線程,內存可用
  • 使用「線程池」,讓我們說的128個線程最多,因爲你所有的「打工皇帝」。當工作線程完成一項工作時,它只是檢查待處理的工作隊列以查看是否有任何事情正在等待完成,如果有,則將該作業從隊列中移除並開始工作。
0

這是一種選擇,較低水平的解決方案然後超過上述規定NotifyingBlocking執行 - 它可能並不如理想,但會簡單地實現

如果你想在待機狀態的線程很多,那麼你最終需要一種機制讓他們知道什麼時候可以「過世」。這聽起來像信號量的情況。

確保它開始工作之前,每個線程不分配不必要的內存。然後實現如下:

1)上的應用程序,存儲在隊列中的啓動創建n個線程。您可以將此n作爲Runtime.getMemory(...)的結果,而不是對其進行硬編碼。

2)同樣,用n-k許可證創建一個信號量。再次,根據可用內存的數量。

3)現在,讓每個的n-k個線程週期性地檢查,如果信號量允許,調用檢查之間的Thread.sleep(...),例如。

4)如果線程通知許可證,則更新信號量並獲取許可證。

如果這可以滿足您的需求,那麼您可以稍後使用更復雜的輪詢或等待/鎖定機制繼續管理您的線程。

2

我遇到類似的問題,最近,我用這個網站所描述的NotifyingBlockingThreadPoolExecutor解決方案:

http://today.java.net/pub/a/today/2008/10/23/creating-a-notifying-blocking-thread-pool-executor.html

的基本想法是,這NotifyingBlockingThreadPoolExecutor會像ThreadPoolExecutor的並行執行任務,但如果你嘗試添加一個任務,並沒有可用的線程,它會等待。它允許我用簡單的「一旦我需要它們就創建我需要的所有任務」的代碼,同時避免一次實例化等待任務的巨大開銷。

這是從你的問題不清楚,但如果你使用的直螺紋,而不是執行人和的Runnable,你應該瞭解java.util.concurrent包裝和使用,而不是:http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html