CompletionSerivce为什么一直阻塞,结果获取不到?

新手上路,请多包涵

使用的是以下代码:


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 使用CompletionService解决Future的缺点
 *
 * @author xiaoshu
 */
public class Test1 {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        MyCallable username1 = new MyCallable("username1", 5);
        MyCallable username2 = new MyCallable("username2", 4);
        MyCallable username3 = new MyCallable("username3", 3);
        MyCallable username4 = new MyCallable("username4", 2);
        MyCallable username5 = new MyCallable("username5", 1);
        List<Callable> callables = new ArrayList<>();
        callables.add(username1);
        callables.add(username2);
        callables.add(username3);
        callables.add(username4);
        callables.add(username5);

        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        ExecutorCompletionService<Object> csRef = new ExecutorCompletionService<>(poolExecutor);
        for (int i = 0; i < 5; i++) {
            Future future = poolExecutor.submit(callables.get(i));
        }

        for (int i = 0; i < 5; i++) {
            System.out.println("等待打印第" + (i + 1) + "个返回值");
            System.out.println(csRef.take().get());
        }

        //System.out.println("main method End!");
    }
}

class MyCallable implements Callable<String> {
    private String username;
    private long sleepValue;

    public MyCallable(String username, long sleepValue) {
        this.username = username;
        this.sleepValue = sleepValue;
    }

    @Override
    public String call() throws Exception {
        System.out.println(username + " " + sleepValue);
        Thread.sleep(sleepValue);
        return "return " + username;
    }
}

控制台输出如下:

clipboard.png

从结果来看,就像是线程被阻塞了,一直获取不到结果,求解!!!

阅读 1.7k
2 个回答
@Override
public String call() throws Exception {
    System.out.println(username + " " + sleepValue);
    Thread.sleep(sleepValue);//应该是这里时间太短了, csRef.take().get()在等待几个已经完成过的callable了吧。
    return "return " + username;
}
新手上路,请多包涵

感谢帮助!
找到原因了.

ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
        ExecutorCompletionService<Object> csRef = new ExecutorCompletionService<>(poolExecutor);
        for (int i = 0; i < 5; i++) {
            Future future = csRef.submit(callables.get(i));//这个地方,提交线程使用csRef,而不是之前的线程池
        }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题