Java多线程 05-线程池
问题1 请实现线程的复用
class Main{
public static void main(String[] args) {
Worker worker = new Worker();
worker.setTask(new Runnable() {
@Override
public void run() {
System.out.println("1111111111111111");
}
});
Thread thread = new Thread(worker);
thread.start();
worker.setTask(new Runnable() {
@Override
public void run() {
System.out.println("2222222222222222");
}
});
}
}
class Worker implements Runnable{
private Runnable task;
@Override
public void run() {
for (int i = 0; ; i++) {
task.run();
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void setTask(Runnable task) {
this.task = task;
}
}
结果:
一、 为什么需要线程池
- 降低资源消耗
- 提高响应速度
- 提高线程的可管理性
二、如何创建线程池
java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类。
方式一 ThreadPoolExecutor构造方法
1 七个参数(七个小矮人)
核心三个:
- int corePoolSize(核心线程数):最小可以同时运行的线程数
- int maximumPoolSize最大(最大线程数):任务队列满时,可以同时运行的线程数
- BlockingQueue workQueue
其他线程参数:
- long keepAliveTime:当线程池中的线程数量大于 corePoolSize 的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了 keepAliveTime才会被回收销毁
- TimeUnit unit:keepAliveTime 参数的时间单位
- ThreadFactory threadFactory:executor 创建新线程的时候会用到
- RejectedExecutionHandler handler:饱和策略。
饱和策略
- ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。
- ThreadPoolExecutor.DiscardOldestPolicy: 此策略将丢弃最早的未处理的任务请求。
方式二 Executors
本质上还是ThreadPoolExecutor。
重要的几个类
1. newSingleThreadExecutor
-
单线程化线程池
-
实现:
ExecutorService threadPool = Executors.newSingleExecutor(); threadPool.execute(线程);
2.newFixedThreadPool
- 固定数目的线程
- ExecutorService threadPool = Executors.newFixedThreadPool(int n);
3.newCachedThreadPool
-
创建一个可缓存的线程池。
-
线程池的数量大于实际需要,回收部分空闲(60秒不执行任务)的线程,小于时,添加线程。
-
线程数目不限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
-
实现:
ExecutorService threadPool = Executors.newCachedThreadPool();
4.newSchedulThreadExecutor
- 创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
- 实现:
ScheduledThreadPoolExecutor scheduled = new ScheduledThreadPoolExecutor(2);
scheduled.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
loge("time:");
}
}, 0, 40, TimeUnit.MILLISECONDS);
//0表示首次执行任务的延迟时间,
//40表示每次执行任务的间隔时间,
//TimeUnit.MILLISECONDS执行的时间间隔数值单位