此处将为大家介绍关于核心队列大小为0的ThreadPoolExecutor在任务队列已满之前不应执行任务的详细内容,并且为您解答有关核心线程数最大线程数队列的相关问题,此外,我们还将为您介绍关于and
此处将为大家介绍关于核心队列大小为0的ThreadPoolExecutor在任务队列已满之前不应执行任务的详细内容,并且为您解答有关核心线程数 最大线程数 队列的相关问题,此外,我们还将为您介绍关于android – 在threadpoolexecutor中停止运行任务的最佳方法是什么?、Executor框架(二)Executors、ThreadPoolExecutor以及线程池执行任务的行为方式、Java Thread Pool Example using Executors and ThreadPoolExecutor、java – ThreadPoolExecutor和队列的有用信息。
本文目录一览:
核心队列大小为0的ThreadPoolExecutor在任务队列已满之前不应执行任务(核心线程数 最大线程数 队列)
我正在学习 Java Concurrency in Practice, 并陷入了 8.3.1线程创建和拆除的
主题。以下脚注警告要保持corePoolSize
为零。
有时,开发人员倾向于将核心大小设置为零,以使工作线程最终被拆除,因此不会阻止JVM退出,但这会在不使用a的线程池中引起一些奇怪的现象。他们的工作队列使用SynchronousQueue(就像newCachedThreadPool一样)。
如果池已经达到核心大小,则ThreadPoolExecutor仅在工作队列已满时才创建新线程。
因此,提交给具有任何容量且核心大小为零的工作队列的线程池的任务要等到队列填满后才能执行,这通常是不希望的。
因此,为了验证这一点,我编写了此程序,但该程序无法如上所述运行。
final int corePoolSize = 0; ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); // If the pool is already at the core size if (tp.getPoolSize() == corePoolSize) { ExecutorService ex = tp; // So tasks submitted to a thread pool with a work queue that has any capacity // and a core size of zero will not execute until the queue fills up. // So, this should not execute until queue fills up. ex.execute(() -> System.out.println("Hello")); }
输出 : 你好
因此,程序的行为是否建议ThreadPoolExecutor
如果提交任务而与无关地创建至少一个线程corePoolSize=0
。如果是,那么教科书中的警告是什么。
编辑: 在 @SK 的建议下,对 jdk1.5.0_22中 的代码进行了以下更改测试:
ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1));//Queue size is set to 1.
但是,有了此更改,程序将终止而不打印任何输出。
那么我会从书中误解这些陈述吗?
编辑(@sjlee): 很难在注释中添加代码,因此我将其添加为编辑内容…您可以尝试此修改并针对最新的JDK和JDK 1.5运行它吗?
final int corePoolSize = 0;ThreadPoolExecutor tp = new ThreadPoolExecutor(corePoolSize, 1, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>());// If the pool is already at the core sizeif (tp.getPoolSize() == corePoolSize) { ExecutorService ex = tp; // So tasks submitted to a thread pool with a work queue that has any capacity // and a core size of zero will not execute until the queue fills up. // So, this should not execute until queue fills up. ex.execute(() -> System.out.println("Hello"));}tp.shutdown();if (tp.awaitTermination(1, TimeUnit.SECONDS)) { System.out.println("thread pool shut down. exiting.");} else { System.out.println("shutdown timed out. exiting.");}
@sjlee已在评论中发布了结果。
答案1
小编典典 ThreadPoolExecutor
在Java 5中,当核心池大小为零时,这种奇怪的行为显然被认为是一个错误,并且在Java 6中已悄然修复。
实际上,由于在6至7之间进行了一些代码修改,该问题在Java 7中再次出现。然后,该问题被报告为错误,被确认为错误并已解决。
无论哪种方式,都不应使用受此错误影响的Java版本。Java 5于2015年停产,并且Java 6及更高版本的最新可用版本不受影响。“
Java并发实践”中的该部分不再合适。
参考文献:
- http://cs.oswego.edu/pipermail/concurrency-interest/2006-December/003453.html (阅读整个主题)
- http://gee.cs.oswego.edu/dl/concurrency-interest/index.html(请参阅
ThreadPoolExecutor
JSR166y捆绑包中的版本。) - https://bugs.openjdk.java.net/browse/JDK-7091003)

android – 在threadpoolexecutor中停止运行任务的最佳方法是什么?
我正在Android中实现Java ThreadPoolExecutor.我需要停止并从池中删除正在运行的任务.
我已经使用submit(Runnable)和Future.cancel()方法实现了这一点.
提交任务的代码如下:
public Future<?> submitTask(Runnable runnableTask) throws CustomException {
if (runnableTask == null) {
throw new CustomException("Null RunnableTask.");
}
Future<?> future = threadPoolExecutor.submit(runnableTask);
return future;
}
submit()返回的Future传递给下面的方法.
取消任务的代码如下:
public void cancelRunningTask(Future<?> future) throws CustomException {
if (future == null) {
throw new CustomException("Null Future<?>.");
}
if (!(future.isDone() || future.isCancelled())) {
if (future.cancel(true))
MyLogger.d(this, "Running task cancelled.");
else
MyLogger.d(this, "Running task cannot be cancelled.");
}
}
问题:任务实际上没有被取消.请让我知道我错在哪里.任何帮助,将不胜感激.
解决方法:
有关Future任务,请参阅documentation.据我所知,如果执行开始,我们无法取消它.然后我们可以做的是取消取消的效果是中断正在运行Future任务的线程
mayInterruptIfRunning - true
在runnable内部,在不同的地方,您需要检查线程是否中断并在中断时返回,这样我们就可以取消它.
Thread.isInterrupted()
样品:
private Runnable ExecutorRunnable = new Runnable() {
@Override
public void run() {
// Before coming to this run method only, the cancel method has
// direct grip. like if cancelled, it will avoid calling the run
// method.
// Do some Operation...
// Checking for thread interruption
if (Thread.currentThread().isInterrupted()) {
// Means you have called Cancel with true. So either raise an
// exception or simple return.
}
// Do some Operation...
// Again Checking for thread interruption
if (Thread.currentThread().isInterrupted()) {
// Means you have called Cancel with true. So either raise an
// exception or simple return.
}
// Similarly you need to check for interruption status at varIoUs
// points
}
};

Executor框架(二)Executors、ThreadPoolExecutor以及线程池执行任务的行为方式
本文已同步至个人博客liaosi''s blog-Executor框架(二)Executors、ThreadPoolExecutor以及线程池执行任务的行为方式
ThreadPoolExecutor
ThreadPoolExecutor是Executor框架最重要的一个类,它即是真正意义上的线程池。该类的源码有两千多行,但大部分是注释说明,而且还有一些private/protected的方法,真正会用到的方法也并不太多。
先了解一下它的构造器。
ThreadPoolExecutor的构造器
ThreadPoolExecutor的构造器有4个重载的构造器,其中有两个ThreadFactory和RejectedExecutionHandler类型的参数是可选的。最完整的构造器如下:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
*
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
构造器的各个参数说明:
-
corePoolSize:核心线程数,核心线程会一直存活,即使没有任务需要处理。但如果设置了
allowCoreThreadTimeOut
`为 true 则核心线程也会超时退出。
-
maximumPoolSize:最大线程数,线程池中可允许创建的最大线程数。
-
keepAliveTime:当线程池中的线程数大于核心线程数,那些多余的线程空闲时间达到keepAliveTime后就会退出,直到线程数量等于corePoolSize。如果设置了
allowCoreThreadTimeout
设置为true,则所有线程均会退出直到线程数量为0。
-
unit:keepAliveTime参数的时间单位
-
workQueue:在任务执行前用来保存任务的 阻塞队列。这个队列只会保存通过execute方法提交到线程池的Runnable任务。在ThreadPoolExecutor线程池的API文档中,一共推荐了三种等待队列,它们是:SynchronousQueue、LinkedBlockingQueue 和 ArrayBlockingQueue。
-
threadFactory:线程池创建新线程时使用的factory。默认使用defaultThreadFactory创建线程。
-
handle:饱和策略。当线程池的线程数已达到最大,并且任务队列已满时来处理被拒绝任务的策略。默认使用ThreadPoolExecutor.AbortPolicy,任务被拒绝时将抛出RejectExecutorException
除此之外,ThreadPoolExecutor还有两个个常用的参数设置:
-
allowCoreThreadTimeout:是否允许核心线程空闲退出,默认值为false。
-
queueCapacity:任务队列的容量。
ThreadPoolExecutor线程池的逻辑结构图:

线程池执行任务的行为方式
线程池按以下行为执行任务
1. 当线程数小于核心线程数时,创建线程。
2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
3. 当线程数大于等于核心线程数,且任务队列已满
1. 若线程数小于最大线程数,创建线程
2. 若线程数等于最大线程数,抛出异常,拒绝任务

Executors
Executors类是一个工厂类,提供了一系列静态工厂方法来创建不同的ExecutorService或 ScheduledExecutorService实例。
创建3种不同的ExecutorService(线程池)实例
1.newSingleThreadExecutor
创建一个单线程的线程池:启动一个线程负责按顺序执行任务,先提交的任务先执行。
其原理是:任务会被提交到一个队列里,启动的那个线程会从队里里取任务,然后执行,执行完,再从队列里取下一个任务,再执行。如果该线程执行一个任务失败,并导致线程结束,系统会创建一个新的线程去执行队列里后续的任务,不会因为前面的任务有异常导致后面无辜的任务无法执行。
源码:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
2.newFixedThreadPool
创建一个可重用的固定线程数量的线程池。即corePoolSize=线程池中的线程数= maximumPoolSize。
- 如果没有任务执行,所有的线程都将等待。
- 如果线程池中的所有线程都处于活动状态,此时再提交任务就在队列中等待,直到有可用线程。
- 如果线程池中的某个线程由于异常而结束时,线程池就会再补充一条新线程。
源码:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
3.newCachedThreadPool
创建一个不限制线程数量的动态线程池。
- 因为有多个线程存在,任务不一定会按照顺序执行。
- 一个线程完成任务后,空闲时间达到60秒则会被结束。
- 在执行新的任务时,当线程池中有之前创建的空闲线程就使用这个线程,否则就新建一条线程。
源码:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
可以看到newCachedThreadPool
使用的队列是SynchronousQueue
,和前两个是不一样的。线程池的线程数可达到Integer.MAX_VALUE,即2147483647。此外由于会有线程的创建和销毁,所以会有一定的系统开销。
4.newSingleThreadExecutor 与 newFixedThreadPool(1) 的区别
JavaDoc上说:
Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
举个例子:
((ThreadPoolExecutor)newFixedThreadPool(1)).setCorePoolSize(3);
即newFixedThreadPool(1)
可以后期修改线程数,不保证线程只有一个。而newSingleThreadExecutor
可以保证。
创建ScheduledExecutorService实例
关于ScheduledExecutorService的内容,在下一篇文章中介绍。
1.newSingleThreadScheduledExecutor
创建一个单线程的ScheduledExecutorService,在指定延时之后执行或者以固定的频率周期性的执行提交的任务。在线程池关闭之前如果有一个任务执行失败,并导致线程结束,系统会创建一个新的线程接着执行队列里的任务。
源码:
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1)); //corePoolSize为1
}
还有一个重载的方法,多了一个ThreadFactory参数,ThreadFactory是用来确定新线程应该怎么创建的。
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1, threadFactory));
}
2.newScheduledThreadPool
创建一个固定线程数的ScheduledExecutorService对象,在指定延时之后执行或者以固定的频率周期性的执行提交的任务。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
同样的,也有一个重载的方法:
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

Java Thread Pool Example using Executors and ThreadPoolExecutor
A thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to get executed. A thread pool manages the collection of Runnable threads and worker threads execute Runnable from the queue.
java.util.concurrent.Executors
provide implementation of
java.util.concurrent.Executor
interface to create the thread pool in java.
Let’s write a simple program to explain it’s working.
First we need to have a Runnable class.
01 |
package com.journaldev.threadpool; |
03 |
public class WorkerThread implements Runnable { |
05 |
private String command; |
07 |
public WorkerThread(String s){ |
13 |
System.out.println(Thread.currentThread().getName()+'' Start. Command = ''+command); |
15 |
System.out.println(Thread.currentThread().getName()+'' End.''); |
18 |
private void processCommand() { |
21 |
} catch (InterruptedException e) { |
27 |
public String toString(){ |
Here is the test program where we are creating fixed thread pool from Executors framework.
01 |
package com.journaldev.threadpool; |
03 |
import java.util.concurrent.ExecutorService; |
04 |
import java.util.concurrent.Executors; |
06 |
public class SimpleThreadPool { |
08 |
public static void main(String[] args) { |
09 |
ExecutorService executor = Executors.newFixedThreadPool(5); |
10 |
for (int i = 0; i < 10; i++) { |
11 |
Runnable worker = new WorkerThread('''' + i); |
12 |
executor.execute(worker); |
15 |
while (!executor.isTerminated()) { |
17 |
System.out.println(''Finished all threads''); |
In above program, we are creating fixed size thread pool of 5 worker threads. Then we are submitting 10 jobs to this pool, since the pool size is 5, it will start working on 5 jobs and other jobs will be in wait state, as soon as one of the job is finished, another job from the wait queue will be picked up by worker thread and get’s executed.
Here is the output of the above program.
01 |
pool-1-thread-2 Start. Command = 1 |
02 |
pool-1-thread-4 Start. Command = 3 |
03 |
pool-1-thread-1 Start. Command = 0 |
04 |
pool-1-thread-3 Start. Command = 2 |
05 |
pool-1-thread-5 Start. Command = 4 |
10 |
pool-1-thread-3 Start. Command = 8 |
12 |
pool-1-thread-2 Start. Command = 9 |
13 |
pool-1-thread-1 Start. Command = 7 |
14 |
pool-1-thread-5 Start. Command = 6 |
15 |
pool-1-thread-4 Start. Command = 5 |
The output confirms that there are five threads in the pool named from “pool-1-thread-1? to “pool-1-thread-5? and they are responsible to execute the submitted tasks to the pool.
Executors class provide simple implementation of ExecutorService using ThreadPoolExecutor but ThreadPoolExecutor provides much more feature than that. We can specify the number of threads that will be alive when we create ThreadPoolExecutor instance and we can limit the size of thread pool and create our own RejectedExecutionHandler implementation to handle the jobs that can’t fit in the worker queue.
Here is our custom implementation of RejectedExecutionHandler interface.
01 |
package com.journaldev.threadpool; |
03 |
import java.util.concurrent.RejectedExecutionHandler; |
04 |
import java.util.concurrent.ThreadPoolExecutor; |
06 |
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler { |
09 |
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { |
10 |
System.out.println(r.toString() + '' is rejected''); |
ThreadPoolExecutor provides several methods using which we can find out the current state of executor, pool size, active thread count and task count. So I have a monitor thread that will print the executor information at certain time interval.
01 |
package com.journaldev.threadpool; |
03 |
import java.util.concurrent.ThreadPoolExecutor; |
05 |
public class MyMonitorThread implements Runnable |
07 |
private ThreadPoolExecutor executor; |
11 |
private boolean run=true; |
13 |
public MyMonitorThread(ThreadPoolExecutor executor, int delay) |
15 |
this.executor = executor; |
19 |
public void shutdown(){ |
28 |
String.format(''[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s'', |
29 |
this.executor.getPoolSize(), |
30 |
this.executor.getCorePoolSize(), |
31 |
this.executor.getActiveCount(), |
32 |
this.executor.getCompletedTaskCount(), |
33 |
this.executor.getTaskCount(), |
34 |
this.executor.isShutdown(), |
35 |
this.executor.isTerminated())); |
37 |
Thread.sleep(seconds*1000); |
38 |
} catch (InterruptedException e) { |
Here is the thread pool implementation example using ThreadPoolExecutor.
01 |
package com.journaldev.threadpool; |
03 |
import java.util.concurrent.ArrayBlockingQueue; |
04 |
import java.util.concurrent.Executors; |
05 |
import java.util.concurrent.ThreadFactory; |
06 |
import java.util.concurrent.ThreadPoolExecutor; |
07 |
import java.util.concurrent.TimeUnit; |
09 |
public class WorkerPool { |
11 |
public static void main(String args[]) throws InterruptedException{ |
12 |
//RejectedExecutionHandler implementation |
13 |
RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl(); |
14 |
//Get the ThreadFactory implementation to use |
15 |
ThreadFactory threadFactory = Executors.defaultThreadFactory(); |
16 |
//creating the ThreadPoolExecutor |
17 |
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, newArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler); |
18 |
//start the monitoring thread |
19 |
MyMonitorThread monitor = new MyMonitorThread(executorPool, 3); |
20 |
Thread monitorThread = new Thread(monitor); |
21 |
monitorThread.start(); |
22 |
//submit work to the thread pool |
23 |
for(int i=0; i<10; i++){ |
24 |
executorPool.execute(new WorkerThread(''cmd''+i)); |
29 |
executorPool.shutdown(); |
30 |
//shut down the monitor thread |
Notice that while initializing the ThreadPoolExecutor, we are keeping initial pool size as 2, maximum pool size to 4 and work queue size as 2. So if there are 4 running tasks and more tasks are submitted, the work queue will hold only 2 of them and rest of them will be handled by RejectedExecutionHandlerImpl.
Here is the output of above program that confirms above statement.
01 |
pool-1-thread-1 Start. Command = cmd0 |
02 |
pool-1-thread-4 Start. Command = cmd5 |
04 |
pool-1-thread-3 Start. Command = cmd4 |
05 |
pool-1-thread-2 Start. Command = cmd1 |
09 |
[monitor] [0/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false |
10 |
[monitor] [4/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false |
15 |
pool-1-thread-1 Start. Command = cmd3 |
16 |
pool-1-thread-4 Start. Command = cmd2 |
17 |
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false |
18 |
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false |
21 |
[monitor] [4/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
22 |
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
23 |
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
24 |
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
25 |
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
26 |
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false |
27 |
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true |
28 |
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true |
Notice the change in active, completed and total completed task count of the executor. We can invoke shutdown() method to finish execution of all the submitted tasks and terminate the thread pool.
Reference: Java Thread Pool Example using Executors and ThreadPoolExecutor from our JCG partner Pankaj Kumar at the Developer Recipes blog.

java – ThreadPoolExecutor和队列
我认为使用
ThreadPoolExecutor我们可以提交Runnables,以便在构造函数中传递的BlockingQueue中执行或使用execute方法执行.
另外我的理解是,如果任务可用,它将被执行.
我不明白的是以下内容:
public class MyThreadPoolExecutor {
private static ThreadPoolExecutor executor;
public MyThreadPoolExecutor(int min,int max,int idleTime,BlockingQueue<Runnable> queue){
executor = new ThreadPoolExecutor(min,max,10,TimeUnit.MINUTES,queue);
//executor.prestartAllCoreThreads();
}
public static void main(String[] main){
BlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
final String[] names = {"A","B","C","D","E","F"};
for(int i = 0; i < names.length; i++){
final int j = i;
q.add(new Runnable() {
@Override
public void run() {
System.out.println("Hi "+ names[j]);
}
});
}
new MyThreadPoolExecutor(10,20,1,q);
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
// Todo Auto-generated catch block
e.printstacktrace();
}
/*executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("++++++++++++++");
}
}); */
for(int i = 0; i < 100; i++){
final int j = i;
q.add(new Runnable() {
@Override
public void run() {
System.out.println("Hi "+ j);
}
});
}
}
}
除非我取消注释executor.prestartAllCoreThreads();否则此代码不会执行任何操作.在构造函数中或者我调用runnable的执行来打印System.out.println(“”); (它也被注释掉了).
为什么?
引用(我的重点):
By default,even core threads are initially created and started only
when new tasks arrive,but this can be overridden dynamically using
method prestartCoreThread() or prestartAllCoreThreads(). You probably
want to prestart threads if you construct the pool with a non-empty
queue.
好.所以我的队列不是空的.但我创建了执行程序,我睡觉然后我将新的Runnables添加到队列中(在循环中为100).
当新任务到来时,这个循环不计算在内吗?
为什么它不起作用,我必须预启动或明确地调用执行?
解决方法
当执行任务到达时,将生成工作线程,这些是与底层工作队列交互的线程.如果以非空工作队列开始,则需要预启动工作程序.见
implementation in OpenJDK 7.
我再说一遍,工人是与工作队列互动的工人.它们仅在通过execute传递时按需生成. (或者它上面的层,例如invokeAll,submit等)如果它们没有启动,那么你添加到队列中的工作量并不重要,因为没有任何工作人员启动就没有检查它.
ThreadPoolExecutor不会在必要之前生成工作线程,或者如果您通过方法prestartAllCoreThreads和prestartCoreThread抢占它们的创建.如果没有工作程序启动,那么您的队列中的任何工作都无法完成.
添加初始执行的原因是它强制创建唯一的核心工作线程,然后该线程可以开始处理队列中的工作.您还可以调用prestartCoreThread并接收类似的行为.如果要启动所有工作程序,则必须调用prestartAllCoreThreads或通过execute提交该数量的任务.
请参阅下面的执行代码.
/**
* Executes the given task sometime in the future. The task
* may execute in a new thread or in an existing pooled thread.
*
* If the task cannot be submitted for execution,either because this
* executor has been shutdown or because its capacity has been reached,* the task is handled by the current {@code RejectedExecutionHandler}.
*
* @param command the task to execute
* @throws RejectedExecutionException at discretion of
* {@code RejectedExecutionHandler},if the task
* cannot be accepted for execution
* @throws NullPointerException if {@code command} is null
*/
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running,try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount,and so prevents false alarms that would add
* threads when it shouldn't,by returning false.
*
* 2. If a task can be successfully queued,then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped,or start a new thread if there are none.
*
* 3. If we cannot queue task,then we try to add a new
* thread. If it fails,we kNow we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command,true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null,false);
}
else if (!addWorker(command,false))
reject(command);
}
关于核心队列大小为0的ThreadPoolExecutor在任务队列已满之前不应执行任务和核心线程数 最大线程数 队列的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于android – 在threadpoolexecutor中停止运行任务的最佳方法是什么?、Executor框架(二)Executors、ThreadPoolExecutor以及线程池执行任务的行为方式、Java Thread Pool Example using Executors and ThreadPoolExecutor、java – ThreadPoolExecutor和队列等相关知识的信息别忘了在本站进行查找喔。