2009-03-06 80 views
8

我想編寫一個永遠運行的命令行守護進程。我知道,如果我希望JVM能夠在Linux中正常關閉,那麼需要通過一些C代碼來封裝引導程序。我想現在可以關閉掛鉤了。Future.get()是Thread.join()的替代品嗎?

在我的問題:

  1. 我的主要(字符串[])塊將火過單獨Superdaemon。
  2. Superdaemon將輪詢和循環永遠。

所以通常我會做的事:

class Superdaemon extends Thread { ... } 

class Bootstrap 
{ 
    public static void main(String[] args) 
    { 
     Thread t = new Superdaemon(); 
     t.start(); 

     t.join(); 
    } 
} 

現在我想如果我通過一個Executor開始Superdaemon,我可以做

Future<?> f = exec.submit(new Superdaemon()); 

f.get(); 

Future.get()與實施的Thread.join() ? 如果不是,它的行爲是否等同?

問候,

阿席達卡

回答

12

是的,你寫這些的方式是等價的。

但是,您並不需要等待Superdaemon線程完成。當主線程完成執行main()時,該線程退出,但JVM不會。 JVM將繼續運行,直到最後一個非守護線程退出其運行方法。

例如,

public class KeepRunning { 
    public static void main(String[] args) { 
    Superdaemon d = new Superdaemon(); 
    d.start(); 
    System.out.println(Thread.currentThread().getName() + ": leaving main()"); 
    } 
} 

class Superdaemon extends Thread { 
    public void run() { 
    System.out.println(Thread.currentThread().getName() + ": starting"); 
    try { Thread.sleep(2000); } catch(InterruptedException e) {} 
    System.out.println(Thread.currentThread().getName() + ": completing"); 
    } 
} 

你會看到輸出:

main: leaving main() 
Thread-0: starting 
Thread-0: completing 

換句話說,主線程完成,然後再輔助線程完成和JVM退出。

0

Sort'a。 Future.get()用於使線程脫機並計算某些內容,然後以安全方式將其返回給調用線程。它會工作,如果get從未返回。但是,我會堅持join的調用,因爲它更簡單,沒有Executer的開銷(不會有那麼多)。

編輯

看起來ExecutorService.submit(Runnable)旨在exectly你試圖做什麼。當Runnable完成時,它僅返回null。有趣。

+0

問題是像JCIP這樣的書正在倡導我們使用Executors來啓動線程。所以我盡我所能不要使用Thread.start()。我不確定我是否會僅僅基於簡單性選擇一種特定的做事方式。必須有更令人信服的理由,不是嗎? – ashitaka 2009-03-06 03:24:50

6

的問題是,書如JCIP提倡大家使用執行人來啓動線程。所以我盡我所能不要使用Thread.start()。我不確定我是否會僅僅基於簡單性選擇一種特定的做事方式。必須有更令人信服的理由,不是嗎?

的說服力的理由使用的java.util.concurrent是多線程編程是非常棘手的。 Java提供了相應的工具(Threads,同步的易失性關鍵字),但這並不意味着您可以直接安全地使用它們而不會讓自己陷入腳下:要麼太多同步,導致不必要的瓶頸和死鎖,或者更少,導致由於競態條件的不穩定行爲)。

With java.util。併發您可以獲得一組實用程序(由專家編寫),以獲取最常見的使用模式,您可以直接使用而不必擔心自己的低級別問題。

你的具體情況,不過,我不太明白爲什麼你需要一個單獨的線程在所有的,你還不如用主要原因之一:

public static void main(String[] args) 
{ 
    Runnable t = new Superdaemon(); 
    t.run(); 
} 

執行人都是爲了工作要在後臺運行(當您有多個並行任務或者當前線程可以繼續執行其他操作時)。