ThreadPoolExecutor修复了具有自定义行为的线程池

Sim*_*lli 8 java multithreading threadpool threadpoolexecutor

我是这个主题的新手......我正在使用用Executors.newFixedThreadPool(10)创建的ThreadPoolExecutor,并且在池已满后我开始得到RejectedExecutionException.有没有办法"强制"执行程序将新任务置于"等待"状态而不是拒绝它并在释放池时启动它?

谢谢

有关此 https://github.com/evilsocket/dsploit/issues/159的问题

涉及的代码行https://github.com/evilsocket/dsploit/blob/master/src/it/evilsocket/dsploit/net/NetworkDiscovery.java#L150

Pet*_*rey 22

如果您使用Executors.newFixedThreadPool(10);它,则排队任务并等待线程准备就绪.

这个方法是

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,使用的队列是无限制的(这本身可能是一个问题),但这意味着队列永远不会填满,您永远不会被拒绝.

顺便说一句:如果你有CPU绑定任务,可以有一个最佳线程数

int processors = Runtime.getRuntime().availableProcessors();
ExecutorService es = Executors.newFixedThreadPool(processors);
Run Code Online (Sandbox Code Playgroud)

可以说明情况的测试类

public static void main(String... args) {
    ExecutorService es = Executors.newFixedThreadPool(2);
    for (int i = 0; i < 1000 * 1000; i++)
        es.submit(new SleepOneSecond());

    System.out.println("Queue length " + ((ThreadPoolExecutor) es).getQueue().size());
    es.shutdown();
    System.out.println("After shutdown");
    try {
        es.submit(new SleepOneSecond());
    } catch (Exception e) {
        e.printStackTrace(System.out);
    }
}

static class SleepOneSecond implements Callable<Void> {
    @Override
    public Void call() throws Exception {
        Thread.sleep(1000);
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

版画

Queue length 999998
After shutdown
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@e026161 rejected from java.util.concurrent.ThreadPoolExecutor@3e472e76[Shutting down, pool size = 2, active threads = 2, queued tasks = 999998, completed tasks = 0]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2013)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:816)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1337)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:132)
    at Main.main(Main.java:17)
Run Code Online (Sandbox Code Playgroud)

  • @SimoneMargaritelli使用`newFixedThreadPool`时应该得到`RejectedExecutionException`的唯一原因是,如果你在调用`shutdown`方法后尝试向执行程序提交任务. (5认同)