线程池
线程池的概念: 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是Java5中引入的,其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作. Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务的线程相当于消费者,并用Runnable、Callable来表示任务,Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。
1.带有缓冲区的线程池
newCachedThreadPool(): 创建一个带有缓冲区的线程池,可根据需要创建新线程,在执行线程任务时先检测线程池是否存在可用线程,如果存在则直接使用,如果不存在则创建新线程然后使用。如果线程池中的线程空闲时间到达60秒后自动回收该线程。适于执行短期线程任务
public class CachedPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//获得一个带有缓冲区的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
//创建一个基于Callable的线程池
Pool2 pool2 = new Pool2();
for (int i=0;i<10;i++) {
Future<Object> future = executorService.submit(pool2); //future表示异步计算的结果
//String str = (String) future.get();
// System.out.println(str);
}
executorService.shutdown();//关闭线程池
}
}
String str = (String) future.get();
表示通过Futrue这个类获得返回值,当调用get方法时,线程将会进入阻塞状态被挂起,所以必须设计这个代码的执行,本文此处将其注释点,不是本章节的重点
2.固定数量的缓冲池
newFixedThreadPool(): 创建一个固定数量的线程池,线程池中的线程数量固定,如果没有空闲线程则新任务处于等待状态,空闲线程不会被回收,适用于执行长期线程任务
public class FixedThreadPool {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);//固定数量为3,核心线程数
Pool2 pool2 =new Pool2();
for(int i=0;i<10;i++){
Future future =executorService.submit(pool2);
}
executorService.shutdown();//一共有10个线程数,核心的有三个也是最大容量,那么剩下的7个被放在等待队列中,等到其中的一个线程执行完毕之后,等待队列的线程开始执行
}
}
3.定时的线程池
newScheduledThreadPool(): 创建一个调度型线程池,可以执行定时任务
public class TimePool {
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
/***
* 启动定时任务
* 参数1:线程任务
* 参数2:延迟时间 程序多少时间后执行
* 参数3:间隔时间
* 参数4:时间单位
*/
scheduledExecutorService.scheduleAtFixedRate(new Pool1(),0,1000, TimeUnit.MILLISECONDS);
//定时器:Timer,TimerTask
scheduledExecutorService.shutdown();
}
}
4.自定义线程池
new ThreadPoolExecutor: 创建一个自定义线程池
public class DIVPool {
/***
* 创建自定义线程池对象
* 参数1:核心线程数(核心线程不会被回收)
* 参数2:最大线程数
* 参数3:非核心线程的最大空闲时间,空闲时间到达后自动回收线程,时间单位由第4个参数指定
* 参数4:时间单位,
* 参数5:等待队列
**/
public static void main(String[] args) {
ArrayBlockingQueue queue = new ArrayBlockingQueue(10);//创建线程等待队列
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,10,100, TimeUnit.MILLISECONDS,queue);
Pool2 pool2 = new Pool2();
for(int i=0;i<10;i++){
executor.submit(pool2);
}
}
}
自定义线程池的等待队列: 当等待队列里边放不下才建立新的线程,当创建18个线程时候,核心线程数5个线程 等待队列容纳10线程 有三个为新建的线程一共执行8个线程,最多只能新建5个线程