池化技术
当程序允许时需要的链接如:JDBC链接,IO链接等等他们开启或关闭会极大的耗费资源,这时则引入了一个池化技术的概念。
池化技术本质:事先准备好一些资源,要用的时候来这里取,用完了在放回去,这样就不用一直开启关闭浪费资源了。
线程池的好处
- 降低资源消耗
- 效率大大提升
- 方便我们管理
线程池三大方法
package JUC.Queue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/*** 三大方法*/public class TestExecutors {public static void main(String[] args) {// ExecutorService executorService = Executors.newSingleThreadExecutor();//单个线程// ExecutorService executorService = Executors.newFixedThreadPool(100);//固定线程池大写ExecutorService executorService = Executors.newCachedThreadPool();//可伸缩的线程池try {for (int i = 0; i < 100; i++) {executorService.execute(()->{System.out.println(Thread.currentThread().getName());});}} finally {//线程池用完一定要关闭executorService.shutdown();}}}
七大参数
源码分析:
//单个线程public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}//固定线程池大写public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}//可伸缩的线程池public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE, //这里最大核心线程约为21亿!60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}//本质开启线程池调用了ThreadPoolExecutor()public ThreadPoolExecutor(int corePoolSize, //核心线程池大小int maximumPoolSize, //最大核心线程池大小long keepAliveTime, //超时了没有人调用就会释放TimeUnit unit, //超时单位BlockingQueue<Runnable> workQueue, //阻塞队列ThreadFactory threadFactory, //线程工厂,创建线程的,一般不动用RejectedExecutionHandler handler) { //拒绝策略if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}
阿里规范手册!
手动创建一个线程池
package JUC.Queue;import java.util.concurrent.*;public class TestThreadPoolExecutor {public static void main(String[] args) {/*** 四种拒绝策略* 1.new ThreadPoolExecutor.AbortPolicy() //线程满了还有线程要进入则,不做处理,直接抛出异常* 2.new ThreadPoolExecutor.CallerRunsPolicy() //那来的那里去* 3.new ThreadPoolExecutor.DiscardPolicy() //队列满了丢掉任务,直接开摆,不会抛出异常!* 4.new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常!*/ThreadPoolExecutor executor = new ThreadPoolExecutor(2,5,2,TimeUnit.SECONDS,new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());//队列满了,尝试去和最早的竞争,也不会抛出异常!for (int i = 0; i < 19; i++) {executor.execute(()->{System.out.println(Thread.currentThread().getName()+"线程");});}}}
四种拒绝策略
- new ThreadPoolExecutor.AbortPolicy() //线程满了还有线程要进入则,不做处理,直接抛出异常
- new ThreadPoolExecutor.CallerRunsPolicy() //那来的那里去
- new ThreadPoolExecutor.DiscardPolicy() //队列满了丢掉任务,直接开摆,不会抛出异常!
- new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会抛出异常!
池的最大的线程如何去设置?
了解:IO密集型与CPU密集型
package JUC.Queue;import java.util.concurrent.*;public class TestThread {public static void main(String[] args) {/*** 最大线程到底该如何定义?* CPU密集型:CPU几核就是几 可以使用Runtime.getRuntime().availableProcessors()方法检测出电脑是几核的* IO密集型:判断程序中十分消耗资源的IO有多少个最大线程数大于它就好了(最好是它的两倍)*/new ThreadPoolExecutor(1,Runtime.getRuntime().availableProcessors(),1,TimeUnit.SECONDS,new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());}}

