2013-05-08 27 views
0

我在使用多線程時遇到了一些非常奇怪的行爲。我有兩個類:DipoleTester和偶極子。Runnable和ExecutorService的奇怪行爲

DipoleTester嘗試創建多個偶極對象,然後異步運行它們。問題是DipoleTester只是一次運行所有偶極子物體,而不是一次運行2個。

這裏是DipoleTester:

public class DipoleTester { 
    public static String DIR = "./save/"; 
    public static void main(String[] args) throws InterruptedException { 
     Dipole trial; 
     ExecutorService service = Executors.newFixedThreadPool(2);  

     for (int r = 10; r < 13; r += 1) { 
      double radius = (double) r/10000.0; 
      for (int matType = 0; matType < 3; matType++) { 
       String name = "Simple_mat"+matType + "_rad" + radius; 
       trial = new DipoleSimple(DIR + "Simple/", name); 
       trial.materialType = matType; 
       trial.RADIUS = radius; 
       service.submit(trial); 

      } 
     } 
     service.shutdown(); 
     service.awaitTermination(100, TimeUnit.HOURS); 
    } 
} 

在這裏,從偶極

public abstract class Dipole implements Runnable{ 
    ...  
    public void run() { 
     initiate(); 
    } 
    public void initiate() { 
     DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); 
     Date date = new Date(); 
     System.out.println(dateFormat.format(date) + ": Starting: " + NAME); 
     model = ModelUtil.create(NAME); 
     model.modelNode().create("mod1"); 
     makeParams(); 
     makeVariables(); 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
    ... 
} 

現在的問題是,所有的線程執行一次是(相關位),即使採用了Thread.Sleep (5000)!我不知道發生了什麼事。這裏是控制檯輸出:

05/08/2013 19:17:31: Starting: Simple_mat0_rad0.001 
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.001 
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.001 
05/08/2013 19:17:31: Starting: Simple_mat0_rad0.0011 
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.0011 
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.0011 
05/08/2013 19:17:31: Starting: Simple_mat0_rad0.0012 
05/08/2013 19:17:31: Starting: Simple_mat1_rad0.0012 
05/08/2013 19:17:31: Starting: Simple_mat2_rad0.0012 
+1

所以你在想,既然線程池只有2個工人,那麼這兩個人會立即鎖定睡眠,其他任務將不得不等待?你想在這裏做什麼?爲什麼不使用調度服務,如果你想他們及時鋪開? – Rob 2013-05-08 23:26:53

+0

你確定它甚至進入了「睡眠」?我修剪了一下你的代碼,讓它能夠編譯並按照你的預期工作,運行2個任務,然後在5秒鐘內運行另外兩個任務。但我不得不拉出一些代碼才能使其工作。也許它正在打破例外,永遠不會進入睡眠狀態? – cmbaxter 2013-05-08 23:39:48

+0

親愛的@randomafk,在每個循環之後''sleep(5000)'應該放在'DipoleTester'類中。在Runnable類中,你不會從睡眠中受益,如果你想在每個循環之後開始一個'sleep'然後在''service.submit(trial)''之後放置'sleep(5000)''。另一件事是你爲什麼不用'service.execute(試用)'而不是'service.submit(trial)' – 2013-05-08 23:41:05

回答

1

Runnable任務拋出一個異常,它獲取到Thread.sleep()調用之前。這允許下一個任務開始執行。所有這些任務都如此快速地失敗,以至於所有任務似乎都在同時運行。

run()方法中第一件事就是致電Thread.sleep(),您將看到一次只能運行兩個線程。

要檢測此類故障,您需要examineFuture實例,該實例由每次調用submit()產生。批量存在other methods for submitting a list of tasks,並等待它們完成,這可能更適合您的應用程序。

+0

同意這一點。我試圖創建一個更簡單的OP代碼版本來測試它,並按照他的意圖工作:http://pastebin.com/UQVuQ5ZL – gerrytan 2013-05-09 00:02:28

+0

同意以及我之前的評論:) – cmbaxter 2013-05-09 00:05:20

+0

非常感謝!我嘗試使用callable和invokeAll()來代替,事實證明我正在使用的庫是在所有地方拋出異常......任何想法爲什麼它會作爲單線程工作,但不是當我嘗試同時運行它們時? – randomafk 2013-05-09 03:47:21