vlambda博客
学习文章列表

java-线程池基本知识

 线程池基本知识


线程池: ThreadPoolExecutor的继承关系如下图

创建一个线程池常用的参数如下:

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:01622882129974==pool-1-thread-1==start1622882129985==pool-1-thread-1==over1622882130072==PoolSize:1==ActiveCount():0;task:1;completed:11622882130172==PoolSize:1==ActiveCount():0;task:1;completed:11622882130273==PoolSize:1==ActiveCount():0;task:1;completed:11622882130374==PoolSize:1==ActiveCount():0;task:1;completed:11622882130475==PoolSize:1==ActiveCount():0;task:1;completed:11622882130576==PoolSize:1==ActiveCount():0;task:1;completed:11622882130676==PoolSize:1==ActiveCount():0;task:1;completed:11622882130777==PoolSize:1==ActiveCount():0;task:1;completed:11622882130878==PoolSize:1==ActiveCount():0;task:1;completed:11622882130974==pool-1-thread-2==start1622882130978==PoolSize:2==ActiveCount():1;task:2;completed:11622882130984==pool-1-thread-2==over1622882131079==PoolSize:2==ActiveCount():0;task:2;completed:21622882131179==PoolSize:2==ActiveCount():0;task:2;completed:21622882131280==PoolSize:2==ActiveCount():0;task:2;completed:21622882131380==PoolSize:2==ActiveCount():0;task:2;completed:21622882131481==PoolSize:2==ActiveCount():0;task:2;completed:21622882131582==PoolSize:2==ActiveCount():0;task:2;completed:21622882131683==PoolSize:2==ActiveCount():0;task:2;completed:21622882131783==PoolSize:2==ActiveCount():0;task:2;completed:21622882131883==PoolSize:2==ActiveCount():0;task:2;completed:21622882131974==pool-1-thread-3==start1622882131984==PoolSize:3==ActiveCount():1;task:3;completed:21622882131985==pool-1-thread-3==over1622882132084==PoolSize:3==ActiveCount():0;task:3;completed:31622882132184==PoolSize:3==ActiveCount():0;task:3;completed:31622882132285==PoolSize:3==ActiveCount():0;task:3;completed:31622882132386==PoolSize:3==ActiveCount():0;task:3;completed:31622882132486==PoolSize:3==ActiveCount():0;task:3;completed:31622882132587==PoolSize:3==ActiveCount():0;task:3;completed:31622882132687==PoolSize:3==ActiveCount():0;task:3;completed:31622882132788==PoolSize:3==ActiveCount():0;task:3;completed:31622882132889==PoolSize:3==ActiveCount():0;task:3;completed:31622882132989==PoolSize:3==ActiveCount():0;task:3;completed:31622882133089==PoolSize:3==ActiveCount():0;task:3;completed:31622882133190==PoolSize:3==ActiveCount():0;task:3;completed:31622882133291==PoolSize:3==ActiveCount():0;task:3;completed:31622882133391==PoolSize:3==ActiveCount():0;task:3;completed:31622882133492==PoolSize:3==ActiveCount():0;task:3;completed:31622882133592==PoolSize:3==ActiveCount():0;task:3;completed:31622882133692==PoolSize:3==ActiveCount():0;task:3;completed:31622882133793==PoolSize:3==ActiveCount():0;task:3;completed:31622882133894==PoolSize:3==ActiveCount():0;task:3;completed:31622882133994==PoolSize:3==ActiveCount():0;task:3;completed:31622882134095==PoolSize:3==ActiveCount():0;task:3;completed:31622882134196==PoolSize:3==ActiveCount():0;task:3;completed:31622882134297==PoolSize:3==ActiveCount():0;task:3;completed:31622882134397==PoolSize:3==ActiveCount():0;task:3;completed:31622882134498==PoolSize:3==ActiveCount():0;task:3;completed:31622882134598==PoolSize:3==ActiveCount():0;task:3;completed:31622882134698==PoolSize:3==ActiveCount():0;task:3;completed:31622882134799==PoolSize:3==ActiveCount():0;task:3;completed:31622882134900==PoolSize:3==ActiveCount():0;task:3;completed:31622882134975==pool-1-thread-4==start1622882134986==pool-1-thread-4==over1622882135000==PoolSize:4==ActiveCount():0;task:4;completed:41622882135100==PoolSize:4==ActiveCount():0;task:4;completed:41622882135200==PoolSize:4==ActiveCount():0;task:4;completed:41622882135301==PoolSize:4==ActiveCount():0;task:4;completed:41622882135402==PoolSize:4==ActiveCount():0;task:4;completed:41622882135503==PoolSize:4==ActiveCount():0;task:4;completed:41622882135603==PoolSize:4==ActiveCount():0;task:4;completed:41622882135703==PoolSize:4==ActiveCount():0;task:4;completed:41622882135804==PoolSize:4==ActiveCount():0;task:4;completed:41622882135904==PoolSize:4==ActiveCount():0;task:4;completed:41622882136005==PoolSize:4==ActiveCount():0;task:4;completed:4

通过以上运行结果,就会发现当加入新的任务时,不管核心线程有没有空闲都会创建新线程,并且核心线程不会超过空闲时间自动退出。如果想让核心线程超过空闲时间自动退出需要添加  service.allowCoreThreadTimeOut(true);

方法。


注意:

1、如果想设置核心线程超时退出,则keepAliveTime的值不能小于等于0,否则会报错:
if (value && keepAliveTime <= 0) throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
2、keepAliveTime这个值如果设置为0,表示空闲时间为0即在执行完任务没有新任务的情况下非核心线程立即退出(如果设置了allowCoreThreadTimeOut(true)则核心线程也会立即退出),并非网上某些文章写的永久不会退出。