2011-08-19 38 views
1

我triyng實驗多線程編程(新的我),我有一些問題。如何正確使用線程池並從線程中獲取結果?

我正在使用ThreadPoolTaskExecutor與TestTask實現Runnablerun方法睡眠X秒。 Everyting進行得很順利,我所有的TestTask都在不同的線程中執行。好。 現在棘手的部分是我想知道在線程中進行的操作的結果。所以我讀了一些谷歌/堆棧/等東西,我試圖使用Future。而且它不工作好了:/

我用get方法來獲取call方法的結果,部分工作,但TestTask被一個接一個執行(而不是在同一時間(真的嗎?)像以前一樣)。所以我猜我不明白什麼,但我不知道什麼......這就是爲什麼我需要你的幫助!

類至極發射試驗:

public void test(String test) { 

    int max = 5; 
    for (int i = 0; i < max; i++) { 
     TestThreadService.launch(i); 
    } 
    System.out.println("END"); 

} 

的TestThreadService類:

public class TestThreadService { 

private ThreadPoolTaskExecutor taskExecutor; 

public void launch(int i) { 
    System.out.println("ThreadNumber : "+i); 
    taskExecutor.setWaitForTasksToCompleteOnShutdown(false); 
    TestTask testTask = new TestTask(i); 
    FutureTask<Integer> futureOne = new FutureTask<Integer>(testTask); 
    taskExecutor.submit(futureOne); 
    try { 
     Integer result = futureOne.get(); 
     System.out.println("LAUNCH result : "+i+" - "+result); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

public void setTaskExecutor(ThreadPoolTaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
} 

} 

而且TestTask類:

public class TestTask implements Callable<Integer> { 

public Integer threadNumber; 
private Integer valeur; 

    public TestTask(int i) { 
    this.threadNumber = i; 
    } 

    public void setThreadNumber(Integer threadNumber) { 
    this.threadNumber = threadNumber; 
    } 

    @Override 
    public Integer call() throws Exception { 
     System.out.println("Thread start " + threadNumber); 
     // generate sleeping time 
     Random r = new Random(); 
     valeur = 5000 + r.nextInt(15000 - 5000); 
     System.out.println("Thread pause " + threadNumber + " " + valeur); 
     try { 
      Thread.sleep(valeur); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("Thread stop" + threadNumber); 
     return this.valeur; 
    } 

} 

我不壞在Java中,但這是我第一次嘗試使用不同的線程,所以我對我來說很新。

我在做什麼錯了?

謝謝!

回答

1

在你test方法,

TestThreadService.launch(1); 

也許應該

TestThreadService.launch(i); 

主要的東西雖然是

Integer result = futureOne.get(); 

呼叫在launch方法。在FutureTask上調用get()是一個阻塞操作,這意味着在任務完成之前它不會返回。這就是你看到連續行爲的原因。您正在模擬的用例(養殖一堆活動並等待它們完成)並不是ThreadPoolTask​​Executor非常適合的用例。它沒有原始線程所具有的「連接」功能。這beeing說,你想要做的是一樣的東西

public Future<Integer> launch(int i) { 
    System.out.println("ThreadNumber : "+i); 
    taskExecutor.setWaitForTasksToCompleteOnShutdown(false); 
    TestTask testTask = new TestTask(i); 
    FutureTask<Integer> futureOne = new FutureTask<Integer>(testTask); 
    return taskExecutor.submit(futureOne); 
    } 

並在測試方法

public void test(String test) { 
    List<Future<Integer>> tasks = new ArrayList<Future<Integer>>(); 
    int max = 5; 
    for (int i = 0; i < max; i++) { 
     tasks.add(TestThreadService.launch(i)); 
    } 
    for (Future<Integer> task : tasks) { 
     System.out.println("LAUNCH result : " + task.get()); 
    } 
    System.out.println("END"); 

} 
0

也可以移動setWaitForTasksToCompleteOnShutdown(假)爲另一種方法,要不要每次調用你啓動一個線程,就像我看到的那樣(不是很多線程),但是在另一個場景中,有更多的任務:一個不必要和昂貴的工作。您也可以在服務上創建一個名爲:configure()的公共方法;或者,啓動前();在開始創建線程之前。

gluck!