[英]Initializing a thread in a static block?
如果我在靜態塊中啟動一個線程。 jvm 會在加載類之前等待線程完成嗎?
static {
System.out.println("static block");
DataRetrievalThread t = new DataRetrievalThread();
t.run();
}
我嘗試這樣做的原因是因為我想從服務器檢索數據,而獲取數據的時間太長了。 因此,為了保留數據,我想檢索它並將其存儲在一個文件中,以便當客戶端請求它時 - 它不需要調用服務器來獲取信息。
如果我在靜態塊中啟動一個線程。 jvm 會在加載類之前等待線程完成嗎?
呃。 是和否和否。
首先,您的代碼沒有分叉線程。 因此,正如它所寫的那樣,它會阻止類的構造,盡管從技術上講,類是在static
部分運行之前“加載”的。 那是因為您直接在當前主線程中執行run()
方法。 如果你想 fork 線程,那么你應該調用t.start();
.
如果你真的用t.start()
fork 線程,那么不,線程將在后台運行並且不會阻止類初始化。
你真的不應該做這樣的事情。 這是一個非常糟糕的模式。 如果您解釋您要完成的任務,我們應該能夠真正提供幫助。
如果您嘗試將數據預加載到您的程序中,那么您應該在main()
盡早運行加載部分,而不要將其停放在類中的static
初始化程序中。 但是如果你在主線程中運行它,阻止程序,我不明白為什么這比按需發出請求更快。
要考慮的一件事是派生(使用t.start()
)一個后台線程來加載數據,然后有一個保存數據的類。 如果線程及時完成,那么它將預加載數據。 當程序需要數據時,它應該調用該類來獲取它。 如果線程還沒有完成,它可以執行countDownLatch.await()
。 當線程完成下載時,它可以執行countDownLatch.countDown()
。 所以你會得到一些並行性。
就像是:
public class DataLoader {
private volatile Stuff data;
private final CountDownLatch latch = new CountDownLatch(1);
// start the thread, called early in main()
public void init() {
// you pass in this so it can call setData
DataRetrievalThread t = new DataRetrievalThread(this);
t.start();
}
// called from the DataRetrievalThread
public void setData(Stuff data) {
this.data = data;
latch.countDown();
}
public Stuff getData() {
if (data == null) {
latch.await();
}
return data;
}
}
使用run()
您可以在當前線程中執行該方法,然后該類將完成加載。 您需要調用start()
在新線程中運行該方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.