如何将List <linkedblockingqueue <long >>提交给ThreadPoolExecutor,每个线程将选择一个LinkedBlockingQueue并并行执行

时间:2019-04-03 03:31:10

标签: java multithreading threadpool executorservice java-threads

我将Long类型的LinkedBlockingQueue列表提交给ThreadPoolExecutor,条件应为每个线程选择long类型的LinkedBlockingQueue并并行执行

这是我的方法逻辑

public void doParallelProcess() {

    List<LinkedBlockingQueue<Long>> linkedBlockingQueueList = splitListtoBlockingQueues();
    ThreadPoolExecutor executor = new ThreadPoolExecutor(1, linkedBlockingQueueList.size(), 0L,
            TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory());
    Long initial = System.currentTimeMillis();
    try {

        System.out.println("linkedBlockingQueueList begin size is " + linkedBlockingQueueList.size() + "is empty"
                + linkedBlockingQueueList.isEmpty());

        while (true) {
            linkedBlockingQueueList.parallelStream().parallel().filter(q -> !q.isEmpty()).forEach(queue -> {
                Long id = queue.poll();
                MyTestRunnable runnab = new MyTestRunnable(id);
                executor.execute(runnab);
                System.out.println("Task Count: " + executor.getTaskCount() + ", Completed Task Count: "
                        + executor.getCompletedTaskCount() + ", Active Task Count: " + executor.getActiveCount());
            });

            System.out.println("linkedBlockingQueueList end size is " + linkedBlockingQueueList.size() + "is empty"
                    + linkedBlockingQueueList.isEmpty());

            System.out.println("executor service " + executor);

            if (executor.getCompletedTaskCount() == (long) mainList.size()) {
                break;
            }

            while (executor.getActiveCount() != 0) {
                System.out.println("Task Count: " + executor.getTaskCount() + ", Completed Task Count: "
                        + executor.getCompletedTaskCount() + ", Active Task Count: " + executor.getActiveCount());
                Thread.sleep(1000L);
            }

        }
    } catch (Exception e) {
    } finally {
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
    }
} `

如何将LinkedBlockingQueue列表提交到单个线程 例子:

  1. List<LinkedBlockingQueue<Long>>每个LinkedBlockingQueue 包含50个队列数据
  2. List<LinkedBlockingQueue<Long>>的大小 是50
  3. 每个线程应选择一个LinkedBlockingQueue<Long>并执行50个队列 任务。

2 个答案:

答案 0 :(得分:1)

ExecutorService的输入是RunnableCallable。您提交的任何任务都需要实现这两个接口之一。如果要向线程池提交一堆任务并等待它们全部完成,则可以使用invokeAll方法并遍历生成的Future s,调用get关于每个问题:请参见有关类似问题的信息丰富的answer

不过,您不需要将输入任务分批处理。您永远不希望执行程序服务在仍有要做的工作时具有空闲线程!您希望它能够在资源释放后立即抓住下一个任务,并且以这种方式进行批处理与此相反。您的代码正在执行此操作:

while non-empty input lists exist {
    for each non-empty input list L {
        t = new Runnable(L.pop())
        executor.submit(t)
    }
    while (executor.hasTasks()) {
        wait
    }
}

一旦这些任务之一完成,该线程就应该可以自由地进行其他工作。但这不是因为您要等到所有N个任务都完成后再提交。使用invokeAll一次提交所有内容,然后让执行者服务执行其构建的工作。

答案 1 :(得分:0)

Executors类是线程池的主要条目:

    ExecutorService executor = Executors.newCachedThreadPool();
    linkedBlockingQueueList.forEach(queue -> executor.submit(() -> { /* process queue */ }));

如果您确实想自己创建ThreadPoolExecutor(它确实使您可以更好地控制配置),则可以使用至少两种方法指定默认线程工厂:

  1. 忽略线程工厂参数:

        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, linkedBlockingQueueList.size(),
                0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    
  2. 再次使用Executors类来获取默认线程工厂:

        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, linkedBlockingQueueList.size(),
                0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
                Executors.defaultThreadFactory());