2016-01-05 205 views
0

我不明白爲什麼我的簡單程序中的線程總是無法終止。 我認爲它是一個簡單的問題,但我不明白爲什麼。我認爲一個簡單的exec.shutdown();應該關閉我的Threadpool而不用嘗試並捕獲exec.shutdownNow();但大壩不確定。Java:爲什麼線程不會終止

類1:測試(實現一類正在運行的線程池)

public class test { 


public static void main(String[] args) throws InterruptedException{ 

    ExecServicrunnen x = new ExecServicrunnen(); 

    x.runningThreads(); 
    Thread.sleep(10000); 
    x.getThreadtoStop(); 
} 
} 

類2:()實現了與MyTask(一個線程池作爲的Runnable)ExecServicerunnen

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 


public class ExecServicrunnen { 

private volatile boolean solange = true; 


public void runningThreads(){ 
    ExecutorService exec = Executors.newFixedThreadPool(5); 

    while(solange){ 
     exec.execute(new myTask()); 


    } 
    exec.shutdown(); 
    try{ 
     if(!exec.awaitTermination(60, TimeUnit.SECONDS)){ 
      exec.shutdownNow(); 
     } 
    } catch (InterruptedException e){ 
     e.printStackTrace(); 
     exec.shutdownNow(); 
      } 
} 

public void getThreadtoStop(){ 
    solange = false; 
} 
} 

類3: myTask(正在等待一段時間)

public class myTask implements Runnable{ 

public void run() { 

// doSomething 

try { 
    Thread.sleep(10000); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

} 

該程序始終無法終止吃了。

+0

啊現在它編譯了,我改變了x的方法名稱以獲得更好的讀取,但忘記了更改對象本身的方法名稱。 –

+0

線程問題仍然存在。 –

回答

4

僵局。

x.runningThreads();在調用x.getThreadtoStop();之前沒有返回,但x.getThreadtoStop();僅在返回x.runningThreads();後調用。 Voilà,線程永遠不會停下來。

錯誤在於runningThreads()正在同步運行在主線程內而不在其自己的線程中。在等待信號終止時,主線程不能發送自己終止的信號。

無需更改代碼的結構太多,你可以用另一個線程解決這個問題,比如:

public class ExecServicrunnen implements Runnable { 

    private volatile boolean solange = true; 

    // Rename runningThreads() to run(): 
    @Override 
    public void run() { 
    // The former code of runningThreads() here... 
    } 

} 

-

public class test { 


    public static void main(String[] args) throws InterruptedException{ 

    ExecServicrunnen x = new ExecServicrunnen(); 

    // Have ExecServicrunnen run in its own thread: 
    new Thread(x).start(); 

    Thread.sleep(10000); 

    x.getThreadtoStop(); 

    } 

} 

順便說一句,那布爾solange邏輯應該在最而是通過Thread.interrupt()Thread.currentThread().isInterrupted()來實現。

+0

我該如何避免這種情況?因爲每當我在一個線程(main方法)中啓動2個對象時,它將被同步執行。 –

+0

我可以調用getThreadtoStop()中的return或break,並將它放在runningThreads()之前,在等待計數器或任何將在ExecServicerunnen中初始化的地方,但我想有更好的解決方案。 –

+0

請參閱我的編輯建議。 – JimmyB