线程池

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。线程池,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

创建线程池的方法

线程池的作用

线程复用
控制最大并发度
管理线程

5个创建方法

		 //看方法有五种线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5个处理线程
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();//一池一个处理线程
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();//一池N个线程
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);//创建拥有固定线程数量的定时线程任务的线程池
        ExecutorService executorService = Executors.newWorkStealingPool();//创建ForJoin线程池

在这里插入图片描述

线程池应用举例

 public static void main(String[] args) {

        //看方法有五种线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);//一池5个处理线程
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();//一池一个处理线程
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();//一池N个线程
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);//创建拥有固定线程数量的定时线程任务的线程池
        ExecutorService executorService = Executors.newWorkStealingPool();//创建ForJoin线程池

        //模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程
        try {
            for (int i = 0; i < 10; i++) {
                cachedThreadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"\t 办理业务");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cachedThreadPool.shutdown();
        }
    }

高级的创建线程池的方法

 ExecutorService executorService = new ThreadPoolExecutor(
                2,
                5,
                1l,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());
  • 线程池参数解析
    在这里插入图片描述

  • 线程池的线程运行步骤
    在这里插入图片描述

  • 当请求到达线程池时,首先是由核心线程进行接待,当请求数量超过核心线程数后,超过核心线程数的请求会被放到阻塞队列里面去,当请求的数量超过阻塞队列大小时,线程池会开启还未开启的线程(小于等于最大线程数),当请求数量大于阻塞队列的线程数量和最大线程数量之和时,使用拒绝策略处理无法执行的任务

四种拒绝策略

  1. AbortPolicy(默认):直接抛出异常阻止异常运行
  2. CallRunsPolicy:“调用者运行”,不会抛弃任务,也不会抛异常,而是将某些任务回退到调用队列中,如果是Main线程调用的话,会传回给Main线程
pool-1-thread-2	 办理业务
pool-1-thread-3	 办理业务
main	 办理业务
pool-1-thread-1	 办理业务
main	 办理业务
pool-1-thread-2	 办理业务
pool-1-thread-5	 办理业务
pool-1-thread-2	 办理业务
pool-1-thread-3	 办理业务
pool-1-thread-4	 办理业务
pool-1-thread-2	 办理业务
pool-1-thread-5	 办理业务
main	 办理业务
pool-1-thread-1	 办理业务
pool-1-thread-1	 办理业务
  1. DiscardOldestPolicy:抛弃队列中等待最久的任务
  2. DiscardPolicy:直接丢弃任务,不处理也不抛异常

线程池的代码实践

public static void main(String[] args) {

        ExecutorService executorService = new ThreadPoolExecutor(
                2,
                5,
                1l,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());

        //1. AbortPolicy: java.util.concurrent.RejectedExecutionException:
        //2. CallerRunsPolicy:  谁调用回退给谁,main	 办理业务
        //3. DiscardOldestPolicy: 抛弃最老的
        //4. DiscardPolicy : 直接抛弃
        //模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程

        try {
            for (int i = 0; i < 15; i++) {
                executorService.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"\t 办理业务");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }

线程池银行举例

  • 线程池的原理可以类比于到银行办理业务的原理,把银行柜台窗口类比于可处理的线程,把候客厅作为阻塞队列,把进来的客户类比于线程请求
  • 图解
    在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/202545.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!