2012-03-20 70 views
0

我在桌子上敲着我的頭在這裏的朋友。這是我想要完成的。我有一個Main類,它將創建一個新的線程。現在,線程完成工作後,它將執行一些小的清理操作,線程停止。但是,我在UI上有一個「停止」按鈕,當按下時,應該「做一些清理,然後殺死線程。問題是,我似乎無法更新我創建的新線程中的任何內容。Java - 無法停止從主類runnable

下面是一些片段:

主類

runner = new Thread(new Controller1(options)); 
runner.start(); 

在上面的代碼,我打電話給我的控制器1類,並在構造函數中設置一些「選項」這是工作好到目前爲止......

現在,在Controller1類中,這是wha我有...

public volatile static boolean stopped; 

public void run() { 
    while(!stopped){ 
     System.out.println("In run"); 
     startProxy(proxyPort); 
     startWebDriver(); 
     driver.get(http); 
     UIMainJSwing1.updateStartButton(); 
     stopped=true; 
    } 

    //Run killAll to stop webdriver and the proxy 
    killAll(); 
    System.out.println("Thread complete"); 
} 

問題是,從主類,我不能調用或設置「停止」爲true。我可以調用runner.interrupt(),但問題是,由於線程死了,我的killAll()函數永遠不會運行,並且我剩下WebDriver和Proxy仍在運行。

+0

While循環的好處,我想我把它放在那裏,因爲我試圖找到一種方法來阻止我的主要線程。現在我已經刪除了它,是的,它運行一次,但無論如何有一個覆蓋,將它從run()方法和killAll()? – Whnunlife 2012-03-20 15:53:28

+0

該循環中的任何阻塞調用? – Tudor 2012-03-20 16:55:02

+0

@Whnunlife如果你發現任何有用的答案,你應該upvote或接受它,即。格雷的回答。 – 2012-03-20 17:21:54

回答

1

我會在您的主線程中調用thread.interupt()並在Runnable的循環周圍使用try/finally block以確保調用killAll()方法。

public void run() { 
    try { 
     while (!stopped) { 
      ... 
     } 
    } finally { 
     //Run killAll to stop webdriver and the proxy 
     killAll(); 
     System.out.println("Thread complete"); 
    } 
} 

finally塊將始終叫。即使線程中斷或拋出異常。

情侶其他意見:

你提volatile boolean stopped國旗,但要設置,要立即真的在循環的結束,所以我明白爲什麼你有一個循環的。

假設線程沒有運行並立即調用killAll(),那麼它掛在其中一個方法的某處。當您從主線程調用interrupt()時,無論等待什麼都會拋出InterruptedException。但是,由於我沒有看到任何進展,也許這些方法將它重新投擲爲RuntimeException?他們至少應該做一些像下面但這仍然塊的特例:

try { 
    something.wait(); 
} catch (InterruptedException e) { 
    // restore the interrupted condition 
    Thread.currentThread().interrupt(); 
} 

無論在try /最後是去確保killAll叫做正道。

+0

'catch(InterruptedException e){ //恢復中斷條件 Thread.currentThread()。interrupt(); }'如果它在某種'while(true)'loop – artbristol 2012-03-20 16:01:41

+0

True @artbristol中,這可能仍然會帶來異常。我調整了我的答案。謝謝。 – Gray 2012-03-20 16:04:39

+0

問題,這個try/catch,應該在runnable的run()方法中正確嗎? – Whnunlife 2012-03-20 16:17:23

0

首先,您應該捕獲InterruptedException,以便您的killAll()方法得到運行。 只需使用一個試試/終於

其次,爲什麼你不能從你的主要方法設置停止=真?

+0

我試過了,所以我做了測試,在run()裏面,在while語句結尾處刪除停止的= true。所以如果我運行它,它只是一個循環。然後我試着從Main中設置這個值,當點擊按鈕時,循環永遠不會退出。 – Whnunlife 2012-03-20 16:19:34

+0

如果您查看使用「中斷」的代碼,您會在run()方法中看到它是否中斷== true並引發InterruptedException。就像你的停止==真。 重點是:你絕不能從另一個線程強制中斷運行線程。如果執行仍然應該運行,你應該在任何時候在run()中檢查你的代碼。如果不是 - 退出或拋出InterruptedException。全部由你自己:) 而不是停止,你可以使用Thread類中存在的isInterrupted()方法,並從主線程調用interrupt()。 – yggdraa 2012-03-20 16:48:57

+0

感謝那裏的信息,所以我應該基本上有一段時間(!isInterrupted())然後,如果我調用thread.interrupt,它會得到檢查爲真,並得到正確的? – Whnunlife 2012-03-20 16:57:27

0

如果我明白這是正確的,你會誤用while(!stopped)成語。在你的代碼中,檢查它是否不停止一次,然後完成所有事情,設置stopped = true並退出。你只是沒有機會在開始後停止執行。當它開始時,停止的字段將不會再次被調用,直到它結束。

+0

你說得對,現在就談! – Whnunlife 2012-03-20 15:54:12

0

首先,丟失了while(!stopped)stopped=true部分。 你還需要在線程中的每個單獨階段評估stopped(並記住運行killAll()並重新啓用開始按鈕當然)。

+0

我改變了我的run()方法,並將每個函數包裝在if(!stopped)中,這樣,如果我從main中設置stops = true,那麼下一個函數將不會運行,並調用killAll。想想我的工作,看起來像業餘代碼,但哦。 – Whnunlife 2012-03-20 16:55:57