一、概念
使用线程使用过程:
- 创建线程
- 创建任务
- 执行任务
- 关闭线程
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁的创建线程就会大大降低系统的运行效率,因为频繁的创建销毁线程需要时间。线程池就是一个容纳多个线程的容器,线程池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。
优点:
- 降低了资源消耗
- 提高响应速度
- 提高了线程的可管理性
二、JAVA中的四种线程池
ExecutorService接口
1、缓存线程池
特点:长度无限制
使用:
- 判断线程池中是否存在空闲线程,存在则使用;
- 不存在,创建线程并放入线程池,再使用。
创建:
ExecutorService service=Executors.newCachedThreadPool();
ExecutorService service= Executors.newCachedThreadPool();
//指挥线程池执行任务
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"runnable");
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"runnable");
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"runnable");
}
});
2、定长线程池
特点:长度是指定的数值。
使用:
- 判断线程池中是否存在空闲线程,存在则使用;
- 不存在空闲线程,线程池未满的情况下,创建新的线程并加入线程池,然后使用;
- 不存在空闲线程,线程池已满的情况下,等待线程池中出现空闲线程;
创建:
ExecutorService service=Executors.newFixedThreadPool(2);
3、单线程线程池
效果与定长线程长度传入1 时一致。
排队任务,使用单线程线程池。
使用:
- 判断线程池中是否存在空闲线程,存在则使用;
- 不存在空闲线程,线程池未满的情况下,创建新的线程并加入线程池,然后使用;
- 不存在空闲线程,线程池已满的情况下,等待线程池中出现空闲线程;
创建:
ExecutorService service=Executors.newSingleThreadPool();
service.execute(new Runnable(){
@Override
public void run(){
System.out.println(Thread.currentThread.getName);
}
});
4、周期性任务定长线程池
特定:周期任务 定长线程池
使用:
- 判断线程池中是否存在空闲线程,存在则使用;
- 不存在空闲,且线程池未满的情况下,则创建线程并加入线程池,然后使用;
- 不存在空闲,且线程池已满的情况下,等待线程池中出现空闲线程。
周期任务:
定时执行,当某个时机触发时,自动执行任务。
ScheduledExecutorService service= Executors.newScheduledThreadPool(2);
/**
* 定时执行(延迟执行的一次性任务)
* 参数1:Runnable类型的任务
* 参数2:时长数字
* 参数3:时长数字类型
*/
service.schedule(new Runnable() {
@Override
public void run() {
System.out.println("schedule"+Thread.currentThread().getName());
}
},10, TimeUnit.SECONDS);
/**
* 周期性执行(每间隔一段时间执行)
* 参数1:Runnable类型的任务
* 参数2:延迟执行时长数字(第一次执行)
* 参数3:任务执行间隔周期
* 参数4:时长数字类型
*/
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("scheduleAtFixedRate"+Thread.currentThread().getName());
}
},5,3,TimeUnit.SECONDS);