简体   繁体   English

如何使用固定数量的线程在Java中运行特定数量的任务

[英]How to use fixed number of threads to run certain number tasks in Java

I have a specific number of threads THREAD_POOL_SIZE and a bunch of tasks which can exceed the number of threads. 我有特定数量的线程THREAD_POOL_SIZE和一堆任务,这些任务可能超过线程数。 I want to use these k threads to run all my tasks. 我想使用这些k线程来运行我的所有任务。 I have these tasks in a BlockingQueue and each thread returns a result which should be aggregated later. 我在BlockingQueue有这些任务,每个线程返回的结果应在以后聚合。

Here I wrote a simple program where tasks are numbers from 1 to 100 and I am trying to calculate the sum of all number. 在这里,我编写了一个简单的程序,其中的任务是从1到100的数字,我试图计算所有数字的总和。 Each thread will pick a number from the blocking queue and return it. 每个线程将从阻塞队列中选择一个数字并返回。 I am using Future to collect my result and sum it later. 我正在使用Future来收集我的结果并在以后汇总。

The reason for using a BlockingQueue is because I am trying to solve a bigger problem where I can have tasks in a blocking queue and I have certain number of threads to run those tasks. 使用BlockingQueue的原因是因为我试图解决一个更大的问题,即我可以在阻塞队列中有任务,并且我有一定数量的线程来运行这些任务。

I would like to know how I can fix the below code to make the k threads continue processing entries from the blocking queue? 我想知道如何解决以下代码,以使k线程继续处理阻塞队列中的条目?

static class Consumer implements Callable<Integer> {
    private BlockingQueue<Integer> sharedQueue;

    public Consumer(BlockingQueue<Integer> sharedQueue) {
        this.sharedQueue = sharedQueue;
    }

    @Override
    public Integer call() {
        while(true){
            try {
                return sharedQueue.take();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public static void main(String[] args) throws Exception {
    int THREAD_POOL_SIZE = 10;
    int BLOCKING_QUEUE_SIZE = 100;
    BlockingQueue<Integer> sharedQueue = new ArrayBlockingQueue<>(BLOCKING_QUEUE_SIZE);
    ExecutorService execService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    List<Future<Integer>> futures = new ArrayList<>();
    for (int i = 0; i < BLOCKING_QUEUE_SIZE; i++) {
        sharedQueue.add(i);
    }

    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
        futures.add(execService.submit(new Consumer(sharedQueue)));
    }

    int total = 0;
    for (Future<Integer> future : futures) {
        try {
            total += future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    System.out.println("Total count: " + total);
    execService.shutdown();
}

Thanks for your help! 谢谢你的帮助!

You need to add 100 futures to the executor, not 10: 您需要将100个期货添加到执行器,而不是10个:

for (int i = 0; i < THREAD_POOL_SIZE; i++) {

Should be: 应该:

for (int i = 0; i < 100; i++) {

It's curious what you think the queue is really adding here. 您认为队列实际上在此处添加的内容很奇怪。 You can massively simplify your code without it. 没有它,您可以大大简化您的代码。

int THREAD_POOL_SIZE = 10;
ExecutorService execService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
List<Future<Integer>> futures = new ArrayList<>();

for (int i = 0; i < 100; i++) {
    final int j = i;
    futures.add(execService.submit(() -> j));
}

int total = 0;
for (Future<Integer> future : futures) {
    try {
        total += future.get();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
System.out.println("Total count: " + total);
execService.shutdown();

Even a glance at your code shows that your code is a way of an overkill. 即使浏览一下代码,也表明您的代码是一种过大的方法。 There are java classes that handle this stuff for you. 有一些Java类可以为您处理这些事情。 Please look at ExecutorService class and Executors class. 请查看ExecutorService类和Executors类。 ExecutorService and its specific implementations provide a managed thread pooling. ExecutorService及其特定实现提供了托管线程池。 All you need to do is to invoke method newFixedThreadPool of class Executors and then submit all your tasks to that pool. 您需要做的就是调用Executors类的newFixedThreadPool方法,然后将所有任务提交到该池中。 You don't need any queue, your tasks will be managed by the thread pool. 您不需要任何队列,您的任务将由线程池管理。 You can collect your Futures and monitor to see when your tasks are finished. 您可以收集Futures并进行监控,以查看任务何时完成。 It is mor simple then you thought 这很简单,然后您认为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM