优点
Java中线程池是通过Executor框架实现的,该框架中用到了Executor,Executors(代表工具类),ExecutorService,ThreadPoolExecutor这几个类
了解:
重点:
示例
public class ThreadPoolDemo {
public static void main(String[] args) {
// 一池5个处理线程(用池化技术,一定要记得关闭)
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 创建一个只有一个线程的线程池
// ExecutorService threadPool = Executors.newSingleThreadExecutor();
// 创建一个拥有N个线程的线程池,根据调度创建合适的线程
// ExecutorService threadPool = Executors.newCachedThreadPool();
// 模拟10个用户来办理业务,每个用户就是一个来自外部请求线程
try {
// 循环十次,模拟业务办理,让5个线程处理这10个请求
for (int i = 0; i < 10; i++) {
final int tempInt = i;
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName()
+ "\t 给用户:" + tempInt + " 办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭线程池
threadPool.shutdown();
}
}
}
运行结果:
pool-1-thread-3 给用户:2 办理业务
pool-1-thread-5 给用户:4 办理业务
pool-1-thread-4 给用户:3 办理业务
pool-1-thread-2 给用户:1 办理业务
pool-1-thread-1 给用户:0 办理业务
pool-1-thread-2 给用户:8 办理业务
pool-1-thread-5 给用户:6 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-3 给用户:5 办理业务
pool-1-thread-1 给用户:9 办理业务
Process finished with exit code 0
public class ThreadPoolExecutor extends AbstractExecutorService {
...
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> 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.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
...
}
等待队列也已经排满了,再也塞不下新任务了同时,线程池中的max线程也达到了,无法继续为新任务服务。 这时候我们就需要拒绝策略机制合理的处理这个问题。
JDK拒绝策略
你在工作中单一的/固定数的/可变的三种创建线程池的方法,你用那个多?
Executors 中JDK已经给你提供了,为什么不用?
public class MyThreadPoolExecutorDemo {
public static void doSomething(ExecutorService executorService, int numOfRequest) {
try {
//记录策略名称
System.out.println(((ThreadPoolExecutor)executorService).getRejectedExecutionHandler().getClass().getName() + ":");
for (int i = 0; i < numOfRequest; i++) {
final int tempInt = i;
executorService.execute(() -> {
System.out.println(Thread.currentThread().getName() + "\t 给用户:" + tempInt + " 办理业务");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
} catch (Exception e) {
System.err.println(e);
} finally {
executorService.shutdown();
}
}
public static ExecutorService newMyThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
int blockingQueueSize,
RejectedExecutionHandler handler){
return new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
1,//keepAliveTime
TimeUnit.SECONDS,
//指定长度的阻塞队列(不指定则为21亿)
new LinkedBlockingQueue<>(blockingQueueSize),
//默认创建工厂
Executors.defaultThreadFactory(),
handler);
}
public static void main(String[] args) {
// doSomething(newMyThreadPoolExecutor(2, 5, 3, new ThreadPoolExecutor.AbortPolicy()), 8);
// doSomething(newMyThreadPoolExecutor(2, 5, 3, new ThreadPoolExecutor.AbortPolicy()), 9);
// doSomething(newMyThreadPoolExecutor(2, 5, 3, new ThreadPoolExecutor.CallerRunsPolicy()), 11);
// doSomething(newMyThreadPoolExecutor(2, 5, 3, new ThreadPoolExecutor.DiscardOldestPolicy()), 10);
// doSomething(newMyThreadPoolExecutor(2, 5, 3, new ThreadPoolExecutor.DiscardPolicy()), 10);
}
}
java.util.concurrent.ThreadPoolExecutor$AbortPolicy:
pool-1-thread-1 给用户:1 办理业务
pool-1-thread-2 给用户:2 办理业务
pool-1-thread-3 给用户:6 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-5 给用户:8 办理业务
pool-1-thread-2 给用户:3 办理业务
pool-1-thread-3 给用户:4 办理业务
pool-1-thread-1 给用户:5 办理业务
Process finished with exit code 0
java.util.concurrent.ThreadPoolExecutor$AbortPolicy:
pool-1-thread-1 给用户:1 办理业务
pool-1-thread-2 给用户:2 办理业务
pool-1-thread-3 给用户:6 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-5 给用户:8 办理业务
java.util.concurrent.RejectedExecutionException: Task com.xc.day3.MyThreadPoolExecutorDemo$$Lambda$1/960604060@30dae81 rejected from java.util.concurrent.ThreadPoolExecutor@1b2c6ec2[Running, pool size = 5, active threads = 5, queued tasks = 3, completed tasks = 0]
pool-1-thread-1 给用户:3 办理业务
pool-1-thread-3 给用户:5 办理业务
pool-1-thread-5 给用户:4 办理业务
Process finished with exit code 0
java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy:
pool-1-thread-1 给用户:1 办理业务
main 给用户:9 办理业务
pool-1-thread-3 给用户:6 办理业务
pool-1-thread-5 给用户:8 办理业务
pool-1-thread-2 给用户:2 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-3 给用户:4 办理业务
pool-1-thread-2 给用户:3 办理业务
pool-1-thread-4 给用户:5 办理业务
Process finished with exit code 0
java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy:
pool-1-thread-1 给用户:1 办理业务
pool-1-thread-2 给用户:2 办理业务
pool-1-thread-3 给用户:6 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-5 给用户:8 办理业务
pool-1-thread-1 给用户:4 办理业务
pool-1-thread-2 给用户:5 办理业务
pool-1-thread-4 给用户:9 办理业务
Process finished with exit code 0
java.util.concurrent.ThreadPoolExecutor$DiscardPolicy:
pool-1-thread-1 给用户:1 办理业务
pool-1-thread-2 给用户:2 办理业务
pool-1-thread-3 给用户:6 办理业务
pool-1-thread-4 给用户:7 办理业务
pool-1-thread-5 给用户:8 办理业务
pool-1-thread-5 给用户:3 办理业务
pool-1-thread-4 给用户:4 办理业务
pool-1-thread-2 给用户:5 办理业务
Process finished with exit code 0
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有