如何正确使用线程池并从线程中获取结果?
我正在尝试尝试多线程编程(对我来说是新的),但我有一些问题。
我正在使用一个带有 TestTask 的 ThreadPoolTaskExecutor,该 TestTask 实现了 Runnable 和一个休眠 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 方面还不错,但这是我第一次尝试使用不同的线程,所以这对我来说是一种新的体验。
我做错了什么?
谢谢 !
i'm triyng to experiment the multithread programming (new for me) and i have some questions.
I'm using a ThreadPoolTaskExecutor
with a TestTask which implements Runnable
and a run
method wich sleeps for X seconds. Everyting went smoothly and all my TestTask were executed in a different thread. Ok.
Now the tricky part is that i want to know the result of an operation made in the thread. So i read some stuff on Google/stack/etc and i tried to use Future
. And it's not working well anymore :/
I use the get
method to get (oh really ?) the result of the call
method and that part is working but the TestTask are executed one after another (and not at the same time like before). So i'm guessing i didn't understand properly something but i don't know what... and that's why i need your help !
The class wich launch test :
public void test(String test) {
int max = 5;
for (int i = 0; i < max; i++) {
TestThreadService.launch(i);
}
System.out.println("END");
}
The TestThreadService class :
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;
}
}
And the TestTask Class :
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;
}
}
I'm not bad in Java but this is the first time i'm trying to use different thread so i'ts kind a new for me.
What am i doing wrong ?
Thanks !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的
test
方法中,但可能应该是
主要的事情
尽管是在
launch
方法中进行调用, 。对 FutureTask 调用 get() 是一个阻塞操作,这意味着在任务完成之前它不会返回。这就是您看到串行行为的原因。您正在模拟的用例(处理一堆活动并等待它们完成)并不是 ThreadPoolTaskExecutor 非常适合的用例。它不具有原始线程所具有的“连接”功能。也就是说,你想要做的就是在你的测试方法中
In your
test
method,should probably be
Main thing though is the
call in the
launch
method. Callingget()
on a FutureTask is a blocking operation, meaning it will not return until the task is completed. That is why you are seeing a serial behavior. The use-case you are emulating (farming a bunch of activities and waiting for them to complete) is not one that the ThreadPoolTaskExecutor is ideally suited for. It does not have the "join" feature that raw threads have. That beeing said, what you want to do is something likeAnd in your test method
您也可以将 setWaitForTasksToCompleteOnShutdown(false) 移动到另一个方法中,因为每次启动线程时都不会被调用,正如我所见,(不是很多线程),但在另一种情况下,有更多任务:不必要的和昂贵的工作。
您还可以在服务上创建一个公共方法,称为:configure();或者,预启动();在开始创建线程之前。
幸灾乐祸!
also you can move setWaitForTasksToCompleteOnShutdown(false) into another method, for to dont be called each time you launch a thread, which is, as i see, (not very much threads), but in another scenario, with more tasks: an unnecessary and expensive job.
You can also create a public method on service, called: configure(); or, pre-launch(); before you start creating threads.
gluck!