线程池(重点)
一:线程池:三大方法,七大参数,四种拒绝策略
池化技术: 01:程序的运行,本质 :占用系统的资源!优化资源的使用!=>池化技术 02:线程池、连接池、内存池、对象池///......创建、销毁。十分浪费资源 03:池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。
线程池的好处: 01:降低资源的消耗 02:提高响应的速度 03:方便管理 (重点)线程复用、可以控制最大并发数、管理线程二:三大方法:01:Executors.newSingleThreadExecutor() //单个线程代码示例01
1 package pool; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 //Executors 工具类、3大方法 7 8 public class Demo01 { 9 public static void main(String[] args) {10 11 ExecutorService threadpool = Executors.newSingleThreadExecutor(); //单个线程12 13 try {14 for (int i = 0; i < 10; i++) {15 //使用了线程池之后,使用线程池来创建线程16 threadpool.execute(()->{17 System.out.println(Thread.currentThread().getName()+" ok");18 });19 }20 } catch (Exception e) {21 e.printStackTrace();22 } finally {23 //线程池用完,程序结束,关闭线程池24 threadpool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)25 }26 }27 }
运行结果:(10个任务被同一个线程所操作)
02:newFixedThreadPool(int nThreads) //创建一个固定的线程池的大小
代码示例02
1 package pool; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 //Executors 工具类、3大方法 7 8 public class Demo01 { 9 public static void main(String[] args) {10 11 //最多5个线程同时执行,从控制台中查看结果12 ExecutorService threadpool = Executors.newFixedThreadPool(5); //创建一个固定的线程池的大小,(5个线程)13 14 try {15 for (int i = 0; i < 10; i++) {16 //使用了线程池之后,使用线程池来创建线程17 threadpool.execute(()->{18 System.out.println(Thread.currentThread().getName()+" ok");19 });20 }21 } catch (Exception e) {22 e.printStackTrace();23 } finally {24 //线程池用完,程序结束,关闭线程池25 threadpool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)26 }27 }28 }
运行结果:(最高同时有5个线程在执行)
03:newCachedThreadPool() //缓存池,可伸缩的, 遇强则强,遇弱则弱
代码示例03
1 package pool; 2 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 //Executors 工具类、3大方法 7 8 public class Demo01 { 9 public static void main(String[] args) {10 11 ExecutorService threadpool = Executors.newCachedThreadPool(); //缓存池,可伸缩的, 遇强则强,遇弱则弱12 13 try {14 for (int i = 0; i < 10; i++) {15 //使用了线程池之后,使用线程池来创建线程16 threadpool.execute(()->{17 System.out.println(Thread.currentThread().getName()+" ok");18 });19 }20 } catch (Exception e) {21 e.printStackTrace();22 } finally {23 //线程池用完,程序结束,关闭线程池24 threadpool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)25 }26 }27 }
运行结果:(最高同时有10个线程在执行,可伸缩的, 遇强则强,遇弱则弱)
三:七大参数
01:三大方法之源码分析:
1 (1) newSingleThreadExecutor() //单个线程 2 3 public static ExecutorService newSingleThreadExecutor() { 4 return new FinalizableDelegatedExecutorService 5 (new ThreadPoolExecutor(1, 1, 6 0L, TimeUnit.MILLISECONDS, 7 new LinkedBlockingQueue())); 8 } 9 ==================================================================================10 (2) newFixedThreadPool(int nThreads) //创建一个固定的线程池的大小11 12 public static ExecutorService newFixedThreadPool(int nThreads) {13 return new ThreadPoolExecutor(nThreads, nThreads,14 0L, TimeUnit.MILLISECONDS,15 new LinkedBlockingQueue());16 }17 ===================================================================================18 (3) newCachedThreadPool() //缓存池,可伸缩的, 遇强则强,遇弱则弱19 20 public static ExecutorService newCachedThreadPool() {21 return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //Integer.Max_VALUE 约等于21亿 //如果我们有这么多条线程一起跑的话,电脑会OOM(溢出),出现问题22 60L, TimeUnit.SECONDS,23 new SynchronousQueue());24 }25 ====================================================================================26 (4) 三大方法所公共的 ThreadPoolExecutor() 方法27 28 ******7大参数******29 30 public ThreadPoolExecutor(int corePoolSize, //核心线程池大小31 int maximumPoolSize, //最大核心线程池大小32 long keepAliveTime, //超时了没有人调用就会释放33 TimeUnit unit, //超时单位34 BlockingQueue workQueue, //阻塞队列35 ThreadFactory threadFactory, //线程工厂,创建线程的,一般不用动36 RejectedExecutionHandler handler) { //拒绝策略37 if (corePoolSize < 0 ||38 maximumPoolSize <= 0 ||39 maximumPoolSize < corePoolSize ||40 keepAliveTime < 0)41 throw new IllegalArgumentException();42 if (workQueue == null || threadFactory == null || handler == null)43 throw new NullPointerException();44 this.corePoolSize = corePoolSize;45 this.maximumPoolSize = maximumPoolSize;46 this.workQueue = workQueue;47 this.keepAliveTime = unit.toNanos(keepAliveTime);48 this.threadFactory = threadFactory;49 this.handler = handler;50 }
阿里巴巴开发手册中有如下规定:
例如银行办理业务图:
四:四种拒绝策略:
/** * new ThreadPoolExecutor.AbortPolicy() //银行满了,还有人进来,不处理这个人的,抛出异常 * new ThreadPoolExecutor.CallerRunsPolicy() //哪来的去哪里! * new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常! * new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试和最早的竞争,也不会抛出异常 */五:手动(自定义)创建一个线程池: 代码示例01 new ThreadPoolExecutor.AbortPolicy() //银行满了,还有人进来,不处理这个人的,抛出异常
1 package pool; 2 3 import java.util.concurrent.Executors; 4 import java.util.concurrent.LinkedBlockingDeque; 5 import java.util.concurrent.ThreadPoolExecutor; 6 import java.util.concurrent.TimeUnit; 7 8 public class Demo02 { 9 public static void main(String[] args) {10 //自定义线程池!工作中只会使用 ThreadPoolExecutor11 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(12 2, //核心线程池大小13 5, //最大核心线程池大小14 3, //超时了没有人调用就会释放15 TimeUnit.SECONDS, //超时单位16 new LinkedBlockingDeque<>(3), //阻塞队列17 Executors.defaultThreadFactory(), //线程工厂,创建线程的,一般不用动18 new ThreadPoolExecutor.AbortPolicy()); //银行满了,还有人进来,不处理这个人的,抛出异常19 20 try {21 //最大承载数,Deque + Max (队列线程数+最大线程数)22 //超出 抛出 RejectedExecutionException 异常23 for (int i = 1; i <= 9; i++) {24 //使用了线程池之后,使用线程池来创建线程25 threadPool.execute(()->{26 System.out.println(Thread.currentThread().getName()+" ok");27 });28 }29 } catch (Exception e) {30 e.printStackTrace();31 } finally {32 //线程池用完,程序结束,关闭线程池33 threadPool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)34 }35 }36 }
运行结果(对比):
代码示例02 new ThreadPoolExecutor.CallerRunsPolicy() //哪来的去哪里
1 package pool; 2 3 import java.util.concurrent.Executors; 4 import java.util.concurrent.LinkedBlockingDeque; 5 import java.util.concurrent.ThreadPoolExecutor; 6 import java.util.concurrent.TimeUnit; 7 8 public class Demo02 { 9 public static void main(String[] args) {10 //自定义线程池!工作中只会使用 ThreadPoolExecutor11 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(12 2, //核心线程池大小13 5, //最大核心线程池大小14 3, //超时了没有人调用就会释放15 TimeUnit.SECONDS, //超时单位16 new LinkedBlockingDeque<>(3), //阻塞队列17 Executors.defaultThreadFactory(), //线程工厂,创建线程的,一般不用动18 new ThreadPoolExecutor.CallerRunsPolicy()); //哪来的去哪里!19 20 try {21 //最大承载数,Deque + Max (队列线程数+最大线程数)22 //超出 抛出 RejectedExecutionException 异常23 for (int i = 1; i <= 9; i++) {24 //使用了线程池之后,使用线程池来创建线程25 threadPool.execute(()->{26 System.out.println(Thread.currentThread().getName()+" ok");27 });28 }29 } catch (Exception e) {30 e.printStackTrace();31 } finally {32 //线程池用完,程序结束,关闭线程池33 threadPool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)34 }35 }36 }
运行结果:
代码示例03 new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!
1 package pool; 2 3 import java.util.concurrent.Executors; 4 import java.util.concurrent.LinkedBlockingDeque; 5 import java.util.concurrent.ThreadPoolExecutor; 6 import java.util.concurrent.TimeUnit; 7 8 public class Demo02 { 9 public static void main(String[] args) {10 //自定义线程池!工作中只会使用 ThreadPoolExecutor11 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(12 2, //核心线程池大小13 5, //最大核心线程池大小14 3, //超时了没有人调用就会释放15 TimeUnit.SECONDS, //超时单位16 new LinkedBlockingDeque<>(3), //阻塞队列17 Executors.defaultThreadFactory(), //线程工厂,创建线程的,一般不用动18 new ThreadPoolExecutor.DiscardPolicy()); //队列满了,丢掉任务,不会抛出异常!19 20 try {21 //最大承载数,Deque + Max (队列线程数+最大线程数)22 //超出 抛出 RejectedExecutionException 异常23 for (int i = 1; i <= 9; i++) {24 //使用了线程池之后,使用线程池来创建线程25 threadPool.execute(()->{26 System.out.println(Thread.currentThread().getName()+" ok");27 });28 }29 } catch (Exception e) {30 e.printStackTrace();31 } finally {32 //线程池用完,程序结束,关闭线程池33 threadPool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)34 }35 }36 }
运行结果:
04:代码示例 new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试和最早的竞争,也不会抛出异常
1 package pool; 2 3 import java.util.concurrent.Executors; 4 import java.util.concurrent.LinkedBlockingDeque; 5 import java.util.concurrent.ThreadPoolExecutor; 6 import java.util.concurrent.TimeUnit; 7 8 public class Demo02 { 9 public static void main(String[] args) {10 //自定义线程池!工作中只会使用 ThreadPoolExecutor11 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(12 2, //核心线程池大小13 5, //最大核心线程池大小14 3, //超时了没有人调用就会释放15 TimeUnit.SECONDS, //超时单位16 new LinkedBlockingDeque<>(3), //阻塞队列17 Executors.defaultThreadFactory(), //线程工厂,创建线程的,一般不用动18 new ThreadPoolExecutor.DiscardOldestPolicy()); //队列满了,尝试和最早的竞争,也不会抛出异常19 20 try {21 //最大承载数,Deque + Max (队列线程数+最大线程数)22 //超出 抛出 RejectedExecutionException 异常23 for (int i = 1; i <= 9; i++) {24 //使用了线程池之后,使用线程池来创建线程25 threadPool.execute(()->{26 System.out.println(Thread.currentThread().getName()+" ok");27 });28 }29 } catch (Exception e) {30 e.printStackTrace();31 } finally {32 //线程池用完,程序结束,关闭线程池33 threadPool.shutdown(); //(为确保关闭,将关闭方法放入到finally中)34 }35 }36 }
运行结果:
更多资料,扫码添加小助手免费获取