指定ThreadPoolExecutor问题

Sar*_*mun 5 java multithreading threadpool

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

我尝试了新ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS, 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
Run Code Online (Sandbox Code Playgroud)

没有人按原样工作.

Stu*_*son 5

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

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

  • 缺少返回的Future对象submit().但也许这对你来说不是问题.
  • 辅助队列只会ThreadPoolExecutor在提交作业时清空.必须有一个优雅的解决方案,但我还没有看到它.如果您知道将有一系列任务进入StusMagicExecutor当时,这可能不是问题.("可能"是关键词.)一个选项可能是让你提交的任务在StusMagicExecutor完成之后捅到它们?

斯图的魔法执行官:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)