JUC编程:线程池的使用

线程池

线程池的好处:

  1. 降低资源的消耗
  2. 提高响应的速度
  3. 方便管理。

线程复用、可以控制最大并发数、管理线程

三大创建方法

  • ExecutorService threadPool = Executors.newSingleThreadExecutor();// 单个线程
  • ExecutorService threadPool = Executors.newFixedThreadPool(10);// 创建一 个固定的线程池的大小
  • ExecutorService threadPool = Executors.newCachedThreadPool(); // 由执行的线程数决定大小。

具体过程:创建线程池对象—>执行---->关闭线程池

 try {
        for (int i = 1; i <= 10; i++) {
                // 使用了线程池之后,使用线程池来创建线程
                threadPool.execute(()->{
                //执行的线程任务
                    System.out.println(Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 线程池用完,程序结束,关闭线程池
            threadPool.shutdown();
        }

七大参数

一般开发中使用线程池最好不使用Executors去创建对象。如阿里巴巴开发手册所说的:OOM(内存溢出)
在这里插入图片描述
所以应该使用ThreadPoolExecutor来创建线程池
查看源码得到以下:

  • 当执行线程数大于核心线程锁时,其它休眠的线程位置将会启用,最多不超过最大线程数。
  • 当超过最大线程锁的线程任务会在阻塞队列中进行等待。
  • 当此时并发执行的线程任务超过了最大线程数+阻塞队列长度时,拒绝策略起效。

拒绝策略有四种

  • new ThreadPoolExecutor.AbortPolicy() // 同时并发的线程数大于最大线程数+阻塞队列长度时,不处理超过部分的线程任务,直接抛出异常。
  • new ThreadPoolExecutor.DiscardPolicy() //同时并发的线程数大于最大线程数+阻塞队列长度时,直接丢掉超过部分的线程任务,不抛出异常。
  • new ThreadPoolExecutor.CallerRunsPolicy() // 同时并发的线程数大于最大线程数+阻塞队列长度时,超过部分的线程任务回归main主线程执行。
  • new ThreadPoolExecutor.DiscardOldestPolicy() //阻塞队列满了,尝试去和最先执行的线程发起竞争,也不会抛出异常!

源码中的是这样的:

public ThreadPoolExecutor(int corePoolSize, //核心线程数
                              int maximumPoolSize, //最大线程数。最多几个线程并发。
                              long keepAliveTime, //当线程无任务时,几秒后结束该线程
                              TimeUnit unit,//线程结束的时间单位
                              BlockingQueue<Runnable> workQueue,//阻塞队列,限制等候线程数
                              ThreadFactory threadFactory,//线程工厂
                              RejectedExecutionHandler handler)//拒绝策略

举个创建的例子:

ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                Runtime.getRuntime().availableProcessors(),
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy());  //队列满了,尝试去和最早的竞争,也不会抛出异常!

如何选择线程池的大小

  1. IO 密集型 :判断你程序中十分耗IO的线程,有n个,线程池就设置(2n)个

  2. CPU 密集型:一般电脑几核,线程池就设置几个线程,可以保持cpu的效率最高!可以利用Runtime.getRuntime().availableProcessors()获取当前主机的核数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值