2011-08-19 36 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!