自己做网站卖东西需要交税吗,建设银行网站特色,做一个网站怎么做的吗,做阿里巴巴网站多少钱文章目录 一、了解线程池1.1 什么是线程池1.2 为什么需要线程池 二、四种线程池的使用2.1 newFixedThreadPool2.2 newCachedThreadPool2.3 newSingleThreadExecutor2.4 newScheduledThreadPool 三、自定义线程池3.1 线程池七大核心参数3.2 线程池内部处理逻辑 一、了解线程池
… 文章目录 一、了解线程池1.1 什么是线程池1.2 为什么需要线程池 二、四种线程池的使用2.1 newFixedThreadPool2.2 newCachedThreadPool2.3 newSingleThreadExecutor2.4 newScheduledThreadPool 三、自定义线程池3.1 线程池七大核心参数3.2 线程池内部处理逻辑 一、了解线程池
1.1 什么是线程池
线程池就是一个装有多个线程的容器我们不需要关心线程的创建在需要时从线程池获取线程来执行即可。线程池提前创建和维护了一定数量的线程避免线程频繁创建和销毁带来的性能损耗同时能提高响应速度。
1.2 为什么需要线程池
我们需要一个线程来执行任务直接 new 一个不就好了吗确实是这样写个demo直接创建线程就好没必要线程池。但是在并发环境下需要创建多个线程来执行任务每个线程执行的时间都很短频繁的创建和销毁线程会耗费时间因此需要线程池
二、四种线程池的使用
2.1 newFixedThreadPool
创建固定线程数量的线程池
newFixedThreadPool(int nThreads) 源码
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable());}实际调用 ThreadPoolExecutor七大参数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}特点 每个线程都是核心线程使用默认的线程工厂使用默认的拒绝策略 使用
class TaskRunnable implements Runnable{private static int ticketCount 5;Overridepublic synchronized void run() {if(ticketCount 0){System.out.println(Thread.currentThread().getName() 售出第 ticketCount 张票);ticketCount--;}else {System.out.println(Thread.currentThread().getName() 没票了);}}
}
public class Demo12 {public static void main(String[] args) {TaskRunnable taskRunnable new TaskRunnable();ExecutorService executorService Executors.newFixedThreadPool(3);for (int i 0; i 8; i) {executorService.submit(taskRunnable);}}
}pool-1-thread-2 售出第5张票
pool-1-thread-1 售出第4张票
pool-1-thread-3 售出第3张票
pool-1-thread-3 售出第2张票
pool-1-thread-3 售出第1张票
pool-1-thread-1没票了
pool-1-thread-2没票了
pool-1-thread-3没票了分析提交八个任务由三个线程完成。
2.2 newCachedThreadPool
只要有任务需要处理线程池可以无限制地创建新线程如果有空闲的线程可以复用则不会创建新线程。
newCachedThreadPool() 源码
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueueRunnable());}实际调用 ThreadPoolExecutor 七大参数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}特点 无核心线程根据需要动态扩缩容默认情况下空闲线程的存活时间为 60 秒。如果线程在 60 秒内没有被使用将被终止并从缓存中移除 使用
class TaskRunnable implements Runnable{private static int ticketCount 5;Overridepublic synchronized void run() {if(ticketCount 0){System.out.println(Thread.currentThread().getName() 售出第 ticketCount 张票);ticketCount--;}else {System.out.println(Thread.currentThread().getName() 没票了);}}
}
public class Demo12 {public static void main(String[] args) throws InterruptedException {TaskRunnable taskRunnable new TaskRunnable();ExecutorService executorService Executors.newCachedThreadPool();for (int i 0; i 10; i) {executorService.submit(taskRunnable);}Thread.sleep(2000);System.out.println(-----------------------------继续提交-----------------------------------);for (int i 0; i 15; i) {executorService.submit(taskRunnable);}}
}
pool-1-thread-3 售出第5张票
pool-1-thread-10 售出第4张票
pool-1-thread-9 售出第3张票
pool-1-thread-8 售出第2张票
pool-1-thread-7 售出第1张票
pool-1-thread-6没票了
pool-1-thread-2没票了
pool-1-thread-4没票了
pool-1-thread-5没票了
pool-1-thread-1没票了
-----------------------------继续提交-----------------------------------
pool-1-thread-7没票了
pool-1-thread-1没票了
pool-1-thread-6没票了
pool-1-thread-7没票了
pool-1-thread-9没票了
pool-1-thread-3没票了
pool-1-thread-8没票了
pool-1-thread-2没票了
pool-1-thread-12没票了
pool-1-thread-10没票了
pool-1-thread-4没票了
pool-1-thread-7没票了
pool-1-thread-11没票了
pool-1-thread-1没票了
pool-1-thread-5没票了
分析可以发现提交十个任务就创建了十个线程。在继续提交十五个任务时会复用之前的十个线程由于线程不够继续创建了第十一和第十二个线程。
2.3 newSingleThreadExecutor
线程池中只有一个线程
newSingleThreadExecutor() 源码
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueueRunnable()));}实际调用 ThreadPoolExecutor 七大参数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler);}特点 只有一个线程该线程也是核心线程适用于同步场景 使用
class TaskRunnable implements Runnable{private static int ticketCount 5;Overridepublic synchronized void run() {if(ticketCount 0){System.out.println(Thread.currentThread().getName() 售出第 ticketCount 张票);ticketCount--;}else {System.out.println(Thread.currentThread().getName() 没票了);}}
}
public class Demo12 {public static void main(String[] args) throws InterruptedException {TaskRunnable taskRunnable new TaskRunnable();ExecutorService executorService Executors.newSingleThreadExecutor();for (int i 0; i 10; i) {executorService.submit(taskRunnable);}}
}pool-1-thread-1 售出第5张票
pool-1-thread-1 售出第4张票
pool-1-thread-1 售出第3张票
pool-1-thread-1 售出第2张票
pool-1-thread-1 售出第1张票
pool-1-thread-1没票了
pool-1-thread-1没票了
pool-1-thread-1没票了
pool-1-thread-1没票了
pool-1-thread-1没票了分析可以看出只有一个线程在执行任务是串行
2.4 newScheduledThreadPool
延迟执行、定时执行
newScheduledThreadPool(核心线程数) 源码
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}实际调用 ScheduledThreadPoolExecutor(int corePoolSize)
public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE,DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,new DelayedWorkQueue());}
使用
class TaskRunnable implements Runnable{private static int ticketCount 5;Overridepublic synchronized void run() {if(ticketCount 0){System.out.println(Thread.currentThread().getName() 售出第 ticketCount 张票);ticketCount--;}else {System.out.println(Thread.currentThread().getName() 没票了);}}
}
public class Demo12 {public static void main(String[] args) throws InterruptedException {TaskRunnable taskRunnable new TaskRunnable();ScheduledExecutorService scheduledExecutorService Executors.newScheduledThreadPool(5);for (int i 0; i 10; i) {scheduledExecutorService.schedule(taskRunnable,3, TimeUnit.SECONDS);}}
}分析延迟3 秒后执行。
scheduleAtFixedRate1 秒后执行每两秒执行一次
scheduledExecutorService.scheduleAtFixedRate(taskRunnable,1,2,TimeUnit.SECONDS);初始延迟为 0 秒。每次任务执行完成后等待 2 秒再开始下一次执行。任务模拟执行时间为 2 秒。
scheduledExecutorService.scheduleWithFixedDelay(taskRunnable,0,2,TimeUnit.SECONDS);shutdown() 线程池不再接受新任务但会继续执行已经提交的任务直到所有任务执行完毕。
awaitTermination(2,TimeUnit.SECONDS) 判断2 秒内是否能完成全部任务
三、自定义线程池
3.1 线程池七大核心参数
源码
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueueRunnable 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.corePoolSize corePoolSize;this.maximumPoolSize maximumPoolSize;this.workQueue workQueue;this.keepAliveTime unit.toNanos(keepAliveTime);this.threadFactory threadFactory;this.handler handler;}参数说明
1.corePoolSize :核心线程数2.maximumPoolSize:最大线程数核心线程数 核心线程数3.keepAliveTime 非核心线程空闲时间没有任务处理空闲超过该时间线程会处于终止状态4.TimeUnit 空闲时间单位5.BlockingQueue workQueue 任务队列6.ThreadFactory 线程工厂7.RejectedExecutionHandler 拒绝策略
3.2 线程池内部处理逻辑
三问
先问核心线程还够不够用再问任务队列是否已满最后问是否已达到最大线程数如果任务队列已满那么创建非核心线程如果任务队列已满同时达到最大线程数再添加任务则执行拒绝策略。
创建和使用自定义线程池
class TaskRunnable implements Runnable{private static int ticketCount 5;Overridepublic synchronized void run() {if(ticketCount 0){System.out.println(Thread.currentThread().getName() 售出第 ticketCount 张票);ticketCount--;}else {System.out.println(Thread.currentThread().getName() 没票了);}try {Thread.sleep(1000); // 模拟做其他事情} catch (InterruptedException e) {e.printStackTrace();}}
}
public class Demo12 {public static void main(String[] args) throws InterruptedException {// 核心线程数int corePoolSize 2;// 最大线程数int maximumPoolSize 4;// 线程空闲时间long keepAliveTime 10;// 时间单位TimeUnit unit TimeUnit.SECONDS;// 工作队列BlockingQueueRunnable workQueue new LinkedBlockingQueue(2);// 线程工厂ThreadFactory threadFactory Executors.defaultThreadFactory();// 拒绝策略RejectedExecutionHandler handler new ThreadPoolExecutor.AbortPolicy();// 创建自定义线程池ThreadPoolExecutor executor new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);TaskRunnable taskRunnable new TaskRunnable();for (int i 0;i 6; i){executor.execute(taskRunnable);}}
}
当提交的任务数 (最大线程数 任务队列大小)能正常工作
pool-1-thread-1 售出第5张票
pool-1-thread-4 售出第4张票
pool-1-thread-3 售出第3张票
pool-1-thread-2 售出第2张票
pool-1-thread-4 售出第1张票
pool-1-thread-1没票了当提交的任务数 (最大线程数 任务队列大小)触发拒绝策略
Exception in thread main java.util.concurrent.RejectedExecutionException: Task com.binbin.usethread.TaskRunnable34a245ab rejected from java.util.concurrent.ThreadPoolExecutor7cc355be[Running, pool size 4, active threads 4, queued tasks 2, completed tasks 0]at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2065)at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:833)at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1365)at com.binbin.usethread.Demo12.main(Demo12.java:50)
pool-1-thread-1 售出第5张票
pool-1-thread-4 售出第4张票
pool-1-thread-3 售出第3张票
pool-1-thread-2 售出第2张票
pool-1-thread-4 售出第1张票
pool-1-thread-1没票了