核心线程类ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
corePoolSize:线程池的大小(核心线程)
maximumPoolSize:线程池能创建的最大线程数(非核心线程)
keepAliveTime:非核心线程能够空闲的最长时间,超过时间线程终止
unit:时间单位,配合 ↑ 一起用
workQueue:缓存队列,存放等待被执行的任务
threadFactory:线程工厂,用来创建线程,一般有三种
(1)ArrayBlockQueue
(2)LinkedBlockingQueue
(3)SynchronousQueue
handler:拒绝处理策略(4种),线程数量大于最大线程数就会采用
拒绝处理策略
1.ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
2.ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
3.ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
4.ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
关闭线程池的两个方法shutdown和submit,区别是后者会有一个结果返回,一般使用第一种。
Executor
线程池的最上层接口Executor,这个接口定义了一个方法execute(Runnable command),然后会被线程池实现,execute负责传递任务。
关于该方法的四个总结:
1.如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务。
2.如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;
3.如果当前线程池中的线程数目达到maximumPoolSize,则会采取任务拒绝策略进行处理;
4.如果线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。
线程池状态
1.RUNNING:线程池创建后的状态
2.SHUTDOWN:调用shutdown处于SHUTDOWN状态,不能接收新的任务,但是需要等待队列中的任务完成
3.STOP:调用shutdownNow处于STOP状态,不能接收新的任务,尝试终止正在执行的任务
4.TERMINATED(结束):线程池处于SHUTDOWN或STOP状态,所有工作线程摧毁,队列清空或执行结束,会进入这个状态
Executors
一般通过Executors来选择线程池
-
1.Executors.newCachedThreadPool() 缓冲池为Integer.MAX_VALUE (相当于无线)
-
2.Executors.newSingleThreadExecutor() 缓冲池为1
-
3.Executors.newFixedThreadPool(int n) 缓冲池为n
-
4.Executors.newScheduledThreadPool(int n) 缓冲池为n,且支持时间调度
线程池使用
首先先定义三个任务
TaskOne
public class TaskOne implements Runnable{
private volatile String taskOneName;
TaskOne(String name){
taskOneName = name;
System.out.println("TaskOne名字为:"+taskOneName);
}
@Override
public void run() {
System.out.println(taskOneName+",开始执行");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskOneName+"睡了3s");
}
}
TaskTwo
public class TaskTwo implements Runnable {
private volatile String taskTwoName;
TaskTwo(String name){
taskTwoName = name;
System.out.println("TaskTwo名字为:"+taskTwoName);
}
@Override
public void run() {
System.out.println(taskTwoName+",开始执行");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskTwoName+"睡了5s");
}
}
TaskThree
public class TaskThree implements Runnable{
private volatile String taskThreeName;
TaskThree(String name){
taskThreeName = name;
System.out.println("TaskThree名字为:"+taskThreeName);
}
@Override
public void run() {
System.out.println(taskThreeName+",开始执行");
try {
Thread.sleep(7000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskThreeName+"睡了7s");
}
}
CachedThreadPool
public class CachedThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i=0;i<2;i++){
executorService.execute(new TaskOne("One"));
executorService.execute(new TaskTwo("Two"));
executorService.execute(new TaskThree("Three"));
}
executorService.shutdown();
System.out.println("任务全部执行完毕(假)");
while (!executorService.isTerminated()){
}
System.out.println("执行结束(真!)");
}
}
执行结果
FixedThreadPool
public class FixedThreadPoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);
for (int i=0;i<2;i++){
executorService.execute(new TaskOne("One"));
executorService.execute(new TaskTwo("Two"));
executorService.execute(new TaskThree("Three"));
}
executorService.shutdown();
System.out.println("执行结束(假结束)");
while (!executorService.isTerminated()){
}
System.out.println("执行结束(真!)");
}
}
执行结果
SingleThreePool
public class SingleThreePoolTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new TaskOne("one"));
executorService.execute(new TaskTwo("two"));
executorService.execute(new TaskThree("three"));
executorService.shutdown();
while (!executorService.isTerminated()){
}
System.out.println("执行结束(真)");
}
}
执行结果
ScheduledThread
public class ScheduledThreadPoolTest {
public static void main(String[] args) {
//周期时间
scheduledThreadPoolTestOne();
}
public static void scheduledThreadPoolTestOne(){
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
scheduledExecutorService.schedule(new TaskOne("One"),1000,TimeUnit.MILLISECONDS);
scheduledExecutorService.schedule(new TaskTwo("Two"),2000,TimeUnit.MILLISECONDS);
scheduledExecutorService.schedule(new TaskThree("Three"),3000,TimeUnit.MILLISECONDS);
scheduledExecutorService.shutdown();
while (!scheduledExecutorService.isTerminated()){
}
System.out.println("执行结束(真!)");
}
}
执行结果
ThreadPoolExecutor
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
int corePoolSize = 1;
int maximumPoolSize = 3;
long keepAliveTime = 1L;
threadPoolExecutorOneTest(corePoolSize,maximumPoolSize,keepAliveTime);
// threadPoolExecutorTwoTest(corePoolSize,maximumPoolSize,keepAliveTime);
}
//无拒绝处理策略
public static void threadPoolExecutorOneTest(int corePoolSize,int maximumPoolSize,long keepAliveTime) {
ThreadPoolExecutor threadPoolExecutorOne = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));
threadPoolExecutorOne.execute(new TaskOne("One1"));
threadPoolExecutorOne.execute(new TaskOne("One2"));
threadPoolExecutorOne.execute(new TaskOne("One3"));
threadPoolExecutorOne.execute(new TaskTwo("Two1"));
threadPoolExecutorOne.execute(new TaskThree("Three"));
threadPoolExecutorOne.execute(new TaskTwo("Two2"));
threadPoolExecutorOne.execute(new TaskTwo("Two3"));
threadPoolExecutorOne.shutdown();
while (!threadPoolExecutorOne.isTerminated()) {
}
System.out.println("threadPoolExecutor执行完毕");
}
//添加拒绝处理策略(线程数超过最大线程+队列容量)
public static void threadPoolExecutorTwoTest(int corePoolSize,int maximumPoolSize,long keepAliveTime) {
ThreadPoolExecutor threadPoolExecutorTwo = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy());
threadPoolExecutorTwo.execute(new TaskOne("One"));
threadPoolExecutorTwo.execute(new TaskOne("1"));
threadPoolExecutorTwo.execute(new TaskOne("2"));
threadPoolExecutorTwo.execute(new TaskTwo("Two 1"));
threadPoolExecutorTwo.execute(new TaskThree("Three"));
threadPoolExecutorTwo.execute(new TaskTwo("Two2"));
threadPoolExecutorTwo.execute(new TaskTwo("Two3"));
threadPoolExecutorTwo.shutdown();
while (!threadPoolExecutorTwo.isTerminated()) {
}
System.out.println("threadPoolExecutor执行完毕");
}
}
注意:线程数不能超过最大线程数+队列,若超过,执行拒绝策略,核心线程为1个,最大为5个,队列容量3个,核心线程先执行,后面任务进队列,若队列满,使用子线程(最大线程减核心)执行。
继续跟进↓
《学习多线程03》关键字volatile
文章我会持续坚持更新,若有问题可以直接联系我,文章会同步到公众号上!微信搜索【雨季的代码人生】或直接扫码关注,回复“问题”即可。