线程池:用于管理线程对象的池子。
为什么使用线程池?
一个线程大约占用的内存1M.
解决频繁创建线程和销毁线程消耗的性能。
解决大量创建线程而导致的内存泄露问题。
线程池工作模式:
提交任务
核心线程是否达到最大
若否那么执行任务,是则执行下一步
队列是否已满
若否那么任务排队等待,是则执行下一步
线程是否达到最大线程
若否那么创建非核心线程,是则执行下一步
执行饱和策略
饱和后会报错
如何创建线程池
java中提供了两种方式:
第一种: 通过工具类完成线程池的创建.[Executors]. 语法简单。但是阿里巴巴不建议使用
第二种: 通过线程池类: ThreadPoolExecutor类. 语法复杂,但是阿里巴巴建议使用。灵活
线程的根接口: Executor. 里面只有一个方法: execute
子接口: ExecutorService。
第一种方案Executors:
固定大小的线程池对象newFixedThreadPool
单一线程池: newSingleThreadExecutor
可变线程池: newCachedThreadPool
延迟线程池: newScheduledThreadPool
public class Test01 { public static void main(String[] args) { //创建一个固定大小的线程池。返回类型为ExecutorService. // ExecutorService executorService = Executors.newFixedThreadPool(5); //创建单一线程池【池子里面只有一个线程的对象】适合任务顺序执行的。 // ExecutorService executorService = Executors.newSingleThreadExecutor(); //创建可变线程池。【池子中线程的数量会随着任务的大小而变化】 // ExecutorService executorService = Executors.newCachedThreadPool(); //延迟线程池:[指定时间后执行] ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5); //执行线程任务。Runnable Callable. Integer.MAX()整数的最大值。 // for(int i=0;i<10;i++) { //1.必须传递Runnable对象。[1]自己创建一个类实现Runnable接口 [2]匿名内部类对象 [3]lambda表达式: 前提接口必须为函数式接口。 // executorService.execute(new My()); // executorService.execute(new Runnable() { // @Override // public void run() { // System.out.println(Thread.currentThread().getName()+"*************"); // } // }); //表示10秒后执行任务代码块。 // executorService.schedule(()->{ // System.out.println(Thread.currentThread().getName()+"~~~~~~~~~~~~~~~"); // },10, TimeUnit.SECONDS); executorService.scheduleAtFixedRate(()->{ System.out.println(Thread.currentThread().getName()); },5,2,TimeUnit.SECONDS); // } //关闭线程池 } }
execute和submit方法区别?
1. 这两个方法都是用来执行线程任务,但是execute属于Executor类中的方法,而submit属于ExecutorService接口中的方法。 而且submit可以执行runnable和callable类型的任务,而execute只能执行Runnable类型的任务。 submit执行完任务后有返回结果。第二种方式ThreadPoolExecutor
package com.ykq.demo07; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Test02 { public static void main(String[] args) { //核心参数的意思 /** * int corePoolSize,核心线程数的个数 2 * int maximumPoolSize,最大线程数量 5 * long keepAliveTime, 非核心线程允许空闲的时间 * TimeUnit unit, 时间的单位 * BlockingQueue<Runnable> workQueue 堵塞队列中 3 */ BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue(5); ThreadPoolExecutor poolExecutor=new ThreadPoolExecutor(2,6,10, TimeUnit.SECONDS,workQueue); for (int i = 0; i <11; i++) { poolExecutor.submit(()->{ System.out.println(Thread.currentThread().getName()+"~~~~~~~~~~~~~~~~"); }); } } }