java-线程池基本知识
“ 线程池基本知识”
创建一个线程池常用的参数如下:
public ThreadPoolExecutor(
int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//线程空闲时间,超过这个时间则自动退出
TimeUnit unit,//空闲时间单位BlockingQueue<Runnable> workQueue,//任务队列
ThreadFactory threadFactory,//线程工厂(负责创建线程的)
RejectedExecutionHandler handler//拒绝策略)
参数之间的关系:当一个任务进入之后,首先判断当前的线程数有没有超过核心线程数,如果没有超过核心线程数,则继续创建新线程(不管有没有空闲核心线程都会创建新线程),当达到核心线程数的时候,新来的任务则放入到任务队列中,当任务队列满了之后,则判断有没有达到最大线程数,如果没有达到最大线程数并且没有空闲的线程则继续创建新线程(如果存在空闲的线程则不会创建新线程),当达到最大线程数之后,如果还有新来的任务并且此时没有空闲的线程,则执行拒绝策略。
public static void main(String[] args) throws Exception {
ThreadPoolExecutor service = new ThreadPoolExecutor(4, 6, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
// service.allowCoreThreadTimeOut(true);
new Thread(() -> {
while (true) {
System.out.println(
System.currentTimeMillis() + "==PoolSize:" + service.getPoolSize() + "==ActiveCount():" + service.getActiveCount()
+
";task:" + service.getTaskCount() + ";completed:" + service.getCompletedTaskCount());
try {
Thread.sleep(100L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Runnable runnable = getTask();
service.execute(runnable);
Thread.sleep(1000L);
service.execute(runnable);
Thread.sleep(1000L);
service.execute(runnable);
Thread.sleep(3000L);
service.execute(runnable);
}
private static Runnable getTask() {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(System.currentTimeMillis() + "==" + Thread.currentThread().getName() + "==start");
try {
Thread.sleep(10L);
System.out.println(System.currentTimeMillis() + "==" + Thread.currentThread().getName() + "==over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
return runnable;
}
1622882129968==PoolSize:0==ActiveCount():0;task:0;completed:0
1622882129974==pool-1-thread-1==start
1622882129985==pool-1-thread-1==over
1622882130072==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130172==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130273==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130374==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130475==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130576==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130676==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130777==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130878==PoolSize:1==ActiveCount():0;task:1;completed:1
1622882130974==pool-1-thread-2==start
1622882130978==PoolSize:2==ActiveCount():1;task:2;completed:1
1622882130984==pool-1-thread-2==over
1622882131079==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131179==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131280==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131380==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131481==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131582==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131683==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131783==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131883==PoolSize:2==ActiveCount():0;task:2;completed:2
1622882131974==pool-1-thread-3==start
1622882131984==PoolSize:3==ActiveCount():1;task:3;completed:2
1622882131985==pool-1-thread-3==over
1622882132084==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132184==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132285==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132386==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132486==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132587==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132687==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132788==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132889==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882132989==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133089==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133190==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133291==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133391==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133492==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133592==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133692==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133793==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133894==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882133994==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134095==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134196==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134297==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134397==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134498==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134598==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134698==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134799==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134900==PoolSize:3==ActiveCount():0;task:3;completed:3
1622882134975==pool-1-thread-4==start
1622882134986==pool-1-thread-4==over
1622882135000==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135100==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135200==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135301==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135402==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135503==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135603==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135703==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135804==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882135904==PoolSize:4==ActiveCount():0;task:4;completed:4
1622882136005==PoolSize:4==ActiveCount():0;task:4;completed:4
通过以上运行结果,就会发现当加入新的任务时,不管核心线程有没有空闲都会创建新线程,并且核心线程不会超过空闲时间自动退出。如果想让核心线程超过空闲时间自动退出需要添加 service.allowCoreThreadTimeOut(true);
注意:
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");