开发者

How to properly use threadpool and get a result from a thread?

开发者 https://www.devze.com 2023-03-29 12:55 出处:网络
i\'m triyng to experiment the multithread programming (new for me) and i have some questions. I\'m using a ThreadPoolTaskExecutorwith a TestTask which implements Runnable and a run method wich sleeps

i'm triyng to experiment the multithread programming (new for me) and i have some questions.

I'm using a ThreadPoolTaskExecutorwith 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!

0

精彩评论

暂无评论...
验证码 换一张
取 消