线程池
一般流程:创建线程、创建任务、执行任务、关闭线程(在一定时间后可自动关闭)
前情提要:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
需求实现:线程池是一个容纳多个线程的容器,池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。
优点:
- 降低资源消耗
- 提高响应速度
- 提高线程的可管理性
缓存线程池
特点:长度无限制
任务加入后的执行流程:
- 判断线程池是否存在空闲线程
- 存在则使用
- 不存在,则新创建一个线程并放入线程池,然后使用
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
}
});
此时使用缓存线程池创建了两个线程。
定长线程池
特点:长度是制定的数值
任务加入后的执行流程:
- 判断线程是否存在空闲线程
- 存在则使用
- 不存在空闲线程,且线程池未满的情况下,则创建线程并放入线程池,然后使用
- 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
此时使用定长线程池创建了两个线程。
单线程线程池
执行流程:
- 判断线程池的那个线程是否空闲
- 空闲则使用
- 不空闲,则等待池中的单个线程空闲后使用
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"锄禾日当午");
}
});
此时使用单线程线程池执行了两个线程。
周期定长线程池
概述:周期性的执行任务
新创建一个线程池对象:
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
主要方法:service.scheduleAtFixedRate(参数1,参数2,参数3,参数4)
参数1:需要执行的任务
参数2:延迟执行的时长数字(第一次执行在什么时间以后)
参数3:周期时长数字(每个多久执行一次)
参数4:时长数字的单位
例如:
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("锄禾日当午");
}
},3,1,TimeUnit.SECONDS);
任务描述:打印“锄禾日当午”,延迟3s后执行,执行周期为1s。