一、线程池介绍
概念+使用原因:线程池就是提前创建好一些线程放在一起的集合,线程池的工作模式时拿到任务后在自己的池子里找看谁闲着,这个活就让谁去干,
多线程模式下,系统需要不断地启动和关闭新线程,这个过程不但消耗资源而在存在线程间过渡的不安全性。ExecuorService 是Java提供的用于管理线程池的类,主要作用是控制线程数量和重用线程
线程池的构成
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
使用线程池的好处:
1、降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2、提高响应速度:当任务到达时,可以不需要等待线程创建就能立即执行。
3、提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。
二、四种常用线程池
1、可缓存线程池(NewCachedThreadPool)
NewCachedThreadPool:可缓存线程池,先到池子里看一下,以前的可用就直接用,如果现有线程没有可用的,则创建一个新线程并添加到池中。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NewCachedThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
//创建一个可缓存线程池
ExecutorService cachedThreadPool=Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
Thread.sleep(10);
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
}
2、指定工作线程的线程池(NewFixedThreadPool)
NewFixedThreadPool:创建一个指定工作线程数量的线程池。每当提交一个任务就创建一个工作线程,如果工作线程数量达到线程池初始的最大数,则将提交的任务存入到池队列中。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NewFixedThreadPoolDemo {
public static void main(String[] args) {
ExecutorService fixedThreadPool=Executors.newFixedThreadPool(4);
for(int i=0;i<10;i++){
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} ;
}
});
}
}
}
3、定时的线程池newScheduledThreadPool
newScheduledThreadPool:创建一个定时定长而且周期性的执行任务的线程池,
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class newScheduledThreadPoolDemo {
public static void main(String[] args) {
//创建一个定长线程池,
ScheduledExecutorService scheduleThreadPool=Executors.newScheduledThreadPool(5);
scheduleThreadPool.scheduleAtFixedRate(new Runnable() {
public void run(){
System.out.println("延迟1s后每三秒执行一次");
}
} ,1,3, TimeUnit.SECONDS);
}
}
这中间每个都隔了三秒
4、单线程线程池(NewSingleThreadExecutor)
NewSingleThreadExecutor:创建一个单线程化的Executor,Executors.newSingleThreadExecutor()返回一个线程池(这个线程池只有一个线程) ,这个线程池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去。它只会用唯一的工作线程来顺序执行任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class NewSingleThreadExecutorDemo {
public static void main(String[] args) {
//创建一个单线程版的线程池
ExecutorService singleThreadExecutor=Executors.newSingleThreadExecutor();
for(int i=0;i<10;i++){
int index=i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"打印的值是"+index);
}
});
}
}
}
可以看到打印的结果是顺序执行