指定ThreadPoolExecutor问题

指定ThreadPoolExecutor问题

本文介绍了指定ThreadPoolExecutor问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法创建Executor,它总是至少有5个线程,最多20个线程,以及任务的无界队列(意味着没有任务被拒绝)

Is there any way to create Executor that will have always at least 5 threads, and maximum of 20 threads, and unbounded queue for tasks (meaning no task is rejected)

我尝试了新的 ThreadPoolExecutor(5,20,60L,TimeUnit.SECONDS,队列)
,我想到了队列的所有可能性:

I tried new ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS, queue)with all possibilities that I thought of for queue:

new LinkedBlockingQueue() // never runs more than 5 threads
new LinkedBlockingQueue(1000000) // runs more than 5 threads, only when there is more than 1000000 tasks waiting
new ArrayBlockingQueue(1000000) // runs more than 5 threads, only when there is more than 1000000 tasks waiting
new SynchronousQueue() // no tasks can wait, after 20, they are rejected

并且没有人按原样行事。

and none worked as wanted.

推荐答案

这样的事情对你有用吗?我只是把它掀起来所以请戳它。基本上,它实现了一个溢出线程池,用于提供底层的 ThreadPoolExecutor

Maybe something like this would work for you? I just whipped it up so please poke at it. Basically, it implements an overflow thread pool that is used to feed the underlying ThreadPoolExecutor

有两个主要的缺点我看到它:

There are two major draw backs I see with it:


  • 上缺少返回的Future对象submit()。但也许这对你来说不是问题。

  • 当提交作业时,辅助队列只会清空到 ThreadPoolExecutor 。必须有一个优雅的解决方案,但我还没有看到它。如果你知道在 StusMagicExecutor 中会有一连串的任务,那么这可能不是问题。 (可能是关键词。)一个选项可能是让你提交的任务在完成后点击 StusMagicExecutor 吗?

  • The lack of a returned Future object on submit(). But maybe that is not an issue for you.
  • The secondary queue will only empty into the ThreadPoolExecutor when jobs are submitted. There has got to be an elegant solution, but I don't see it just yet. If you know that there will be a stead stream of tasks into the StusMagicExecutor then this may not be an issue. ("May" being the key word.) An option might to be to have your submitted tasks poke at the StusMagicExecutor after they complete?

Stu的魔术执行者:

Stu's Magic Executor:

public class StusMagicExecutor extends ThreadPoolExecutor {
    private BlockingQueue<Runnable> secondaryQueue = new LinkedBlockingQueue<Runnable>();  //capacity is Integer.MAX_VALUE.

    public StusMagicExecutor() {
        super(5, 20, 60L, SECONDS, new SynchronousQueue<Runnable>(true), new RejectionHandler());
    }
    public void queueRejectedTask(Runnable task) {
        try {
            secondaryQueue.put(task);
        } catch (InterruptedException e) {
            // do something
        }
    }
    public Future submit(Runnable newTask) {
        //drain secondary queue as rejection handler populates it
        Collection<Runnable> tasks = new ArrayList<Runnable>();
        secondaryQueue.drainTo(tasks);

        tasks.add(newTask);

        for (Runnable task : tasks)
             super.submit(task);

        return null; //does not return a future!
    }
}

class RejectionHandler implements RejectedExecutionHandler {
    public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
        ((StusMagicExecutor)executor).queueRejectedTask(runnable);
    }
}

这篇关于指定ThreadPoolExecutor问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 07:10