簡體   English   中英

在靜態塊中初始化線程?

[英]Initializing a thread in a static block?

如果我在靜態塊中啟動一個線程。 jvm 會在加載類之前等待線程完成嗎?

static {
    System.out.println("static block");
    DataRetrievalThread t = new DataRetrievalThread();
    t.run();
}

我嘗試這樣做的原因是因為我想從服務器檢索數據,而獲取數據的時間太長了。 因此,為了保留數據,我想檢索它並將其存儲在一個文件中,以便當客戶端請求它時 - 它不需要調用服務器來獲取信息。

如果我在靜態塊中啟動一個線程。 jvm 會在加載類之前等待線程完成嗎?

呃。 是和否和否。

  1. 首先,您的代碼沒有分叉線程。 因此,正如它所寫的那樣,它阻止類的構造,盡管從技術上講,類是在static部分運行之前“加載”的。 那是因為您直接在當前主線程中執行run()方法。 如果你想 fork 線程,那么你應該調用t.start(); .

  2. 如果你真的用t.start() fork 線程,那么不,線程將在后台運行並且不會阻止類初始化。

  3. 你真的應該做這樣的事情。 這是一個非常糟糕的模式。 如果您解釋您要完成的任務,我們應該能夠真正提供幫助。

如果您嘗試將數據預加載到您的程序中,那么您應該在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.

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