闲来无事-关于线程池的一些理解

1:新建测试线程用于观察现象

package com.company.bingfa;

public class MyThread extends Thread {
private String name;
public MyThread(String name){
this.name=name;

}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"task:"+name);
}
}


2:main方法测试:
a:
package com.company.bingfa;

import java.util.concurrent.*;

public class MyMain {
public static void main(String[] args) throws InterruptedException {
/**
* corePoolSize:核心线程数 即基本线程数 运行的线程数
* maximumPoolSize:最大可创建的线程数
* keepAliveTime:空闲线程最大的存活时间,超过这个时间该线程将被回收 比如0 表示线程执行完即可被回收 3表示线程可空闲3秒即可被标记要回收
*/
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(3));
pool.execute(new MyThread("1"));
pool.execute(new MyThread("2"));
pool.execute(new MyThread("3"));
pool.execute(new MyThread("4"));
pool.execute(new MyThread("5"));
pool.execute(new MyThread("6"));
}}
结果:

pool-1-thread-1task:1
pool-1-thread-1task:2
pool-1-thread-1task:3
pool-1-thread-1task:4
pool-1-thread-2task:5

结果分析:

      我们给线程池设置的核心线程也就是运行的线程数是1,最大线程数是2,阻塞队列是3,线程空闲等待时间是0

     也就是说:

                  当task1执行时创建线程1,线程没执行完,task2、task3、task4在队列中等待复用线程1 task5 提交创建线程2 都正常打印

b:

ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(3));
pool.execute(new MyThread("1"));
pool.execute(new MyThread("2"));
pool.execute(new MyThread("3"));
pool.execute(new MyThread("4"));
pool.execute(new MyThread("5"));
pool.execute(new MyThread("6"));
pool.shutdown();

执行结果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task Thread[Thread-5,5,main] rejected from java.util.concurrent.ThreadPoolExecutor@14ae5a5[Running, pool size = 2, active threads = 2, queued tasks = 3, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at com.company.bingfa.MyMain.main(MyMain.java:18)
pool-1-thread-1task:1
pool-1-thread-1task:2
pool-1-thread-1task:3
pool-1-thread-1task:4
pool-1-thread-2task:5

结果分析:报错,触发线程池拒绝策略

      我们给线程池设置的核心线程也就是运行的线程数是1,最大线程数是2,阻塞队列是3,线程空闲等待时间是0

                  当task1执行时创建线程1,线程没执行完,task2、task3、task4在队列中等待复用线程1 task5 提交创建线程2 都正常打印,task6提交 线程1没释放,队列已满 线程2未释放 最大线程为2 已不可创建其余线程故直接触发线程池拒绝策略报错 
c:

ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(3));
pool.execute(new MyThread("1"));
pool.execute(new MyThread("2"));
pool.execute(new MyThread("3"));
pool.execute(new MyThread("4"));
pool.execute(new MyThread("5"));
Thread.sleep(1000);
pool.execute(new MyThread("6"));
pool.shutdown();
执行结果:

pool-1-thread-1task:1
pool-1-thread-2task:5
pool-1-thread-1task:2
pool-1-thread-2task:3
pool-1-thread-1task:4
pool-1-thread-1task:6

结果分析:全部正常打印

      由于线程池的设置线程的闲置时间是0ms,故task5执行完睡眠1s,线程1 和线程2 早已被释放,故此时线程池是空的,可创建新线程,所以正常打印,按照这个逻辑分析,在线程池释放干净后最少可创建6个任务

d:

  ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 500, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(3));
pool.execute(new MyThread("1"));
pool.execute(new MyThread("2"));
pool.execute(new MyThread("3"));
pool.execute(new MyThread("4"));
pool.execute(new MyThread("5"));
Thread.sleep(3);
pool.execute(new MyThread("6"));
pool.shutdown();
}
执行结果:有可能全部正常打印,也有可能报错,因为线程最大闲置时间远大于线程睡眠时间(本案例),那么线程池允许闲置线程存活的时间较长,就可能占用线程池空间其他想进来的线程就进不来,当然也有可能因为线程执行的任务非常简单,瞬间就完事故可能会被立即回收都正常打印

e:
 /**
* corePoolSize:核心线程数 即基本线程数 运行的线程数
* maximumPoolSize:最大可创建的线程数
* keepAliveTime:空闲线程最大的存活时间,超过这个时间该线程将被回收 比如0 表示线程执行完即可被回收 3表示线程可空闲3秒即可被标记要回收
*/
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(3));
pool.execute(new MyThread("1"));
pool.execute(new MyThread("2"));
pool.execute(new MyThread("3"));
pool.execute(new MyThread("4"));
pool.execute(new MyThread("5"));
Thread.sleep(10);
pool.execute(new MyThread("6"));
pool.shutdown();
}
正常打印:
结论:由于线程池闲置线程可存活时间为0故只要线程睡眠时间大于线程执行任务的之间基本能保证线程被释放,即会正常打印


原文地址:https://www.cnblogs.com/coderdxj/p/11787691.html