[英]Java starting a thread pool in objects constructor
在對象構造函數中啟動線程池是否安全? 我知道您不應該從構造函數中啟動線程,有關“ this”指針轉義的內容(我不太了解這一點,但是會進行更多搜索以嘗試找出問題)。
代碼看起來像這樣:
private ExecutorService pool;
public handler()
{
pool = Executors.newCachedThreadPool();
}
public void queueInstructionSet(InstructionSet set)
{
pool.submit(new Runnable that handles this instruction set);
}
如果那不起作用,我可以將其創建為Runnable並在新線程中啟動它。 但是,似乎在程序中確實不需要了一個不必要的線程。
謝謝。
編輯:
感謝大家的答復,他們肯定幫助了他們。
按照代碼,在我看來,該構造函數創建線程池是有意義的,但是讓我解釋一下此代碼的具體作用,因為我可能會以一種怪異的方式來考慮。
該對象的重點是獲取“指令集”對象,並對其進行相應的操作。 指令集來自連接到服務器的客戶端。 從客戶端收到完整的指令集后,該指令集將發送到此對象(處理程序)進行處理。
該處理程序對象包含對指令集可以對其執行操作的每個對象的引用。 它將指令集提交到線程池,該線程池將找到該指令集要與之交互的對象,然后在該對象上處理指令集。
我可以在IO服務器中處理指令集對象,但是我的想法是有一個單獨的類,因為它使整個代碼更具可讀性,因為每個類都只專注於做一件事。
思考? 建議嗎?
謝謝
您的示例代碼根本不會讓“ this”轉義。 只要確定已經將對象初始化到新線程,那么在構造函數中啟動新線程(甚至將this
用作Runnable
,在此示例中就不會使用)是相當安全的。將需要它。 例如, 在啟動線程后設置新線程將依賴的最終字段將是一個非常糟糕的主意:)
基本上讓“ this”引用轉義通常是令人討厭的,但並非普遍如此。 在某些情況下它是安全的。 請注意。
話雖如此,使構造函數啟動線程可能被視為在構造函數內做得太多。 很難說在這種情況下是否合適-我們對您的代碼在做什么並不了解。
編輯:是的,已經閱讀了額外的信息,我認為這是可以的。 您可能還應該有一種關閉線程池的方法。
我同意喬恩的觀點。
此外,讓我指出,您實際上並沒有在構造函數中的線程池上啟動任何操作。 您正在實例化線程池,但是此時它沒有要運行的任務。 因此,按照書面規定,在實例完成構建之前,您將無需對其進行任何操作。
聽起來線程池將由對象擁有和使用; 線程不會從對象中傳遞出去。 如果是這樣,那就不成問題了。
構造函數創建一個對象並初始化其狀態。 我無法想象一個需要長時間運行的流程的用例。
我可以看到一個對象可能在何處與線程池進行交互以完成任務,但是我看不到該對象擁有線程池的必要性。
更多詳細信息可能會有所幫助。
我認為可以在對象的構造函數中啟動線程池,只要該對象完全管理該線程池的生存期即可。
如果您走這條路,您將必須加倍努力以提供以下保證:
destructor
方法,類似於Java I / O中的close
方法。 我通常將其releaseResources
。 請注意, finalize
不能替代此方法,因為它是由GC調用的,並且對於內存占用量較小的對象,可能永遠不會調用它。 - >
MyThreadPoolContainer container =
new MyThreadPoolContainer( ... args to initialize the object... );
try
{
methodThatUsesContainer( container );
}
finally
{
container.releaseResources( );
}
destructor
方法以防止其泄漏。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.