java - 如何正确使用线程池并从线程中获取结果?

标签 java threadpool future

我正在尝试多线程编程(对我来说是新的),但我有一些问题。

我正在使用一个 ThreadPoolTask​​Executor 和一个实现 Runnable 的 TestTask 以及一个 hibernate X 秒的 run 方法。一切都很顺利,我的所有测试任务都在不同的线程中执行。好的。 现在棘手的部分是我想知道线程中操作的结果。所以我在 Google/stack/etc 上阅读了一些内容,并尝试使用 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 能力还不错,但这是我第一次尝试使用不同的线程,所以对我来说这是一种新的体验。

我做错了什么?

谢谢!

最佳答案

在您的测试方法中,

TestThreadService.launch(1);

应该是

TestThreadService.launch(i);

主要的是

Integer result = futureOne.get();

调用launch方法。对 FutureTask 调用 get() 是一个阻塞操作,这意味着在任务完成之前它不会返回。这就是您看到串行行为的原因。您正在模拟的用例(处理一堆 Activity 并等待它们完成)并不是 ThreadPoolTask​​Executor 非常适合的用例。它不具有原始线程所具有的“连接”功能。也就是说,你想做的是这样的

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");

}

关于java - 如何正确使用线程池并从线程中获取结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7122120/

相关文章:

java - 在 Java 中将监听器变成 future

java - JTextField 中字符串的 If 语句

java - Spring 启动: Jenkins removes escaped double quote character from commands

c# - IIS 工作线程与 Web 应用程序线程

c# - StackExchange.Redis.RedisTimeoutException : Timeout awaiting response

c++ - 如何在 C++ 中使用 boost 创建线程池?

java - Scala 的 future 到 Java Completable 的 future

multithreading - 在可能出现异常(exception)情况的将来应用 future

java - 如何处理 "Building workspace has encountered a problem"

Java swing 三个相对组合框