package com.example.sgg.juc;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 线程池示例
* 不推荐使用Executors的4大方法来创建线程池,因为它们的队列长度为21亿,避免OOM
* Created by 奔跑的蜗牛 on 2022/4/21 01:54:25(凌晨了,时间为手编记录)
* 每天学习一点点,每天进步一点点
*
* 推荐:
* 1、bilibili 【狂神说Java】JUC并发编程最新版通俗易懂 P23集
* https://m.bilibili.com/video/BV1B7411L7tE?p=23&share_medium=android&share_plat=android&share_session_id=1250b29c-168d-472a-9eaf-b9b30b9c2a19&share_source=WEIXIN&share_tag=s_i×tamp=1650476960&unique_k=gphr507
* 2、博客:浅谈Java线程池
* https://blog.csdn.net/qq_37883866/article/details/115794698
*/
public class ThreadPoolExecutorDemo {
/**
* 经典案例:银行排队处理业务(太经典了)
* 当前处理窗口个数:2(核心线程数corePoolSize)
* 当等候区满了之后,最大可扩大到最大的处理窗口个数:5(最大线程数maximumPoolSize)
* 当新扩展的窗口没有业务处理超过10分钟,则关闭窗口(超时释放时间keepAliveTime unit)
* 等候大厅的最大可排队数量(队列-数量workQueue)
* 窗口产生设置窗口号(可通过工厂类设置线程命等threadFactory)
* 当等候区满了,窗口也满了的情况下,大厅门口安排拒绝客户进入(拒绝策略RejectedExecutionHandler)
*
* 7大参数展示
* public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
* 4大拒绝策略
* AbortPolicy 直接丢弃任务,并抛出RejectedExecutionException异常
* CallerRunsPolicy 在调用者线程中直接执行被拒绝任务的run方法,除非线程池已经shutdown,则直接抛弃任务
* DiscardPolicy 直接丢弃任务
* DiscardOldestPolicy 抛弃进入队列最早的那个任务,然后尝试把这次拒绝的任务放入队列
* @param args
*/
public static void main(String[] args) {
//银行看做一个线程池
//线程池里的线程相当于银行的窗口
ThreadPoolExecutor pool = new ThreadPoolExecutor(2,
5,
10,
TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(3),
new MyThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
try {
//最大承载数 queue + max
//i相当于客户,为了便于理解,请将i从1变换至10,并依次执行,查看结果
for (int i = 0; i < 10; i++) {
int finalI = i;
pool.execute(() -> System.out.println(Thread.currentThread().getName()+"办理了客户"+ finalI +"的银行业务"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
pool.shutdown();
}
}
/**
* The my thread factory
* 这个工厂类是用于创建线程池里的线程用的
*/
static class MyThreadFactory implements ThreadFactory {
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
MyThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
namePrefix = "农业银行窗口";
}
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
}
|