我很想尝试多线程编程(对我来说是新的)并且我有一些问题。
我正在使用带有TestTask的ThreadPoolTaskExecutor
,它实现Runnable
和run
方法,可以睡眠X秒。一切顺利,所有的TestTask都在不同的线程中执行。好。
现在棘手的部分是我想知道在线程中进行的操作的结果。所以我在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方面还不错,但这是我第一次尝试使用不同的线程,所以对我来说这是一个新的东西。
我做错了什么?
谢谢!
答案 0 :(得分:1)
在test
方法中,
TestThreadService.launch(1);
应该是
TestThreadService.launch(i);
主要的是
Integer result = futureOne.get();
使用launch
方法调用。在FutureTask上调用get()
是一个阻塞操作,这意味着在任务完成之前它不会返回。这就是你看到串行行为的原因。您正在模拟的用例(种植一堆活动并等待它们完成)并不是ThreadPoolTaskExecutor非常适合的用例。它没有原始线程具有的“连接”功能。那个说法,你想要做的就是
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");
}
答案 1 :(得分:0)
你也可以将setWaitForTasksToCompleteOnShutdown(false)移动到另一个方法中,因为每次你启动一个线程都不会被调用,就像我看到的那样(不是很多线程),但在另一个场景中,有更多的任务:这是一项不必要且昂贵的工作。
您还可以在服务上创建一个公共方法,名为:configure();或者,pre-launch();在开始创建线程之前。
格鲁克!