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 setThreadNum开发者_如何学运维ber(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 !
In your test
method,
TestThreadService.launch(1);
should probably be
TestThreadService.launch(i);
Main thing though is the
Integer result = futureOne.get();
call in the launch
method. Calling get()
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 like
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);
}
And in your test method
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");
}
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!
精彩评论