线程池3大方法、7大参数、4种拒绝策略

news/2024/5/20 9:55:18 标签: java, 多线程, 并发编程, juc,

1.池化技术

程序的运行,本质:占用系统的资源! (优化资源的使用 => 池化技术)

线程池、连接池、内存池、对象池///… 创建、销毁。十分浪费资源

池化技术:事先准备好一些资源,有人要用,就来我这里拿,用完之后还给我。

2.线程池的好处

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

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

3.线程池的三大方法

先来看看阿里的开发手册是怎么说使用线程池的
吧!
在这里插入图片描述
在这里插入图片描述

简单代码实现:

java">import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-26 16:34
 **/
public class ThreeOfNew {


    public static void main(String[] args) {


        /**
         * Executors,可以理解为一个工具类 ,创建线程池的三大方法
         */

        //1.创建一个固定大小的线程池
        ExecutorService threadPool = Executors.newFixedThreadPool(5);

        //2.创建单个线程的线程池
        //ExecutorService threadPool = Executors.newSingleThreadExecutor();

        //3.创建一个可伸缩的线程池,大小不固定
        //ExecutorService threadPool = Executors.newCachedThreadPool();
        try {

            for (int i = 1; i <= 10 ; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"is  ok");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //线程池用完后关闭
            threadPool.shutdown();
        }


    }
}

执行结果:
*1.固定大小线程池
在这里插入图片描述
*2.单个线程的线程池
在这里插入图片描述
*3.课伸缩的线程池
在这里插入图片描述
4.线程池七大参数
这里我们源码来一层层分析,首先先来看看三大方法是怎么创建线程池的

java"> public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
java">public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
java">public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

可以看出,都是new了一个 ThreadPoolExcutor

我们再来看看ThreadPoolExcutor的创建

java"> public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小 
                          int maximumPoolSize, // 最大核心线程池大小 
                          long keepAliveTime, // 超时没有人调用就会释放 
                          TimeUnit unit, // 超时单位 
                          // 阻塞队列 
                          BlockingQueue<Runnable> workQueue, 
                          // 线程工厂:创建线程的,一般 不用动
                          ThreadFactory threadFactory,  
                          // 拒绝策略
                          RejectedExecutionHandler handle ) {
    if (corePoolSize < 0 
        || maximumPoolSize <= 0 
        || maximumPoolSize < corePoolSize 
        || keepAliveTime < 0) 
        throw new IllegalArgumentException(); 
    if (workQueue == null 
        || threadFactory == null 
        || handler == null) 
        throw new NullPointerException(); 
    this.acc = System.getSecurityManager() == null 
        ? null : AccessController.getContext(); 
    this.corePoolSize = corePoolSize; 
    this.maximumPoolSize = maximumPoolSize; 
    this.workQueue = workQueue; 
    this.keepAliveTime = unit.toNanos(keepAliveTime); 
    this.threadFactory = threadFactory; 
    this.handler = handler; 
}

为什么阿里不推荐用excutors创建线程池呢?

在这里插入图片描述
这里我们用 在银行取钱的例子来说明一下这七大参数和ThreadPoolExcutorf的妙处吧

举例说明:
在这里插入图片描述
简单代码实现:

因为实际开发中工具类Executors 不安全,所以需要手动创建线程池,自定义7个参数。

这里先说明四种拒绝策略,通过例子说明

java">/**
 * 四种拒绝策略:
 *
 * new ThreadPoolExecutor.AbortPolicy() 
 * 银行满了,还有人进来,不处理这个人的,抛出异常
 *
 * new ThreadPoolExecutor.CallerRunsPolicy() 
 * 哪来的去哪里!比如你爸爸 让你去通知妈妈洗衣服,妈妈拒绝,让你回去通知爸爸洗
 *
 * new ThreadPoolExecutor.DiscardPolicy() 
 * 队列满了,丢掉任务,不会抛出异常!
 *
 * new ThreadPoolExecutor.DiscardOldestPolicy() 
 * 队列满了,尝试去和最早的竞争,也不会抛出异常!
 */

主要代码:

java">import java.util.concurrent.*;

/**
 * @program: juc
 * @description
 * @author: 不会编程的派大星
 * @create: 2021-04-26 17:07
 **/
public class Seven {

    public static void main(String[] args) {


        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                //核心线程池大小,(默认开启的窗口)
                2,
                //最大核心线程池大小(总共5个窗口)
                5,
                //超时3秒没有人调用就会释,关闭窗口
                3,
                // TimeUnit unit, 超时单位 秒
                TimeUnit.SECONDS,
                // 阻塞队列(候客区最多3人)
                new LinkedBlockingDeque<>(3),
                // 默认线程工厂
                Executors.defaultThreadFactory(),
                // 4种拒绝策略之一:
                // 队列满了,尝试去和 最早的竞争,也不会抛出异常!
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );


        try {
            for (int i = 1; i <=10 ; i++) {

                threadPoolExecutor.execute(() -> {
                    System.out.println(Thread.currentThread().getName()+"  窗口可以取钱");
                });
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            threadPoolExecutor.shutdown();
        }

    }
}

执行结果:

在这里插入图片描述
5.四种拒绝策略

在这里插入图片描述

a:

  • new ThreadPoolExecutor.AbortPolicy()
  • 银行满了,还有人进来,不处理这个人的,抛出异常

b:

  • new ThreadPoolExecutor.CallerRunsPolicy()
  • 哪来的去哪里!比如你爸爸 让你去通知妈妈洗衣服,妈妈拒绝,让你回去通知爸爸洗

c:

  • new ThreadPoolExecutor.DiscardPolicy()
  • 队列满了,丢掉任务,不会抛出异常!

d:

  • new ThreadPoolExecutor.DiscardOldestPolicy()
  • 队列满了,尝试去和最早的竞争,也不会抛出异常!
    /***

http://www.niftyadmin.cn/n/1715655.html

相关文章

android怎么操作才会出现anr_Android ANR的产生和解决办法

ANR (Application Not Responding 程序无响应)ANR定义&#xff1a;在Android上&#xff0c;如果你的应用程序有一段时间响应不够灵敏&#xff0c;系统会向用户显示一个对话框&#xff0c;这个对话框称作应用程序无响应(ANR&#xff1a;Application Not Responding)对话框。用户…

四大函数式接口以及Stream流式计算

经过近几年计算机行业的发展&#xff0c;新时代的程序员&#xff1a;lambda表达式、链式编程、函数式接口、Stream流式计算 1.函数式接口 函数式接口&#xff1a; 只有一个方法的接口 Runnable就是一个典型的例子 FunctionalInterface public interface Runnable {public a…

像素位移_EOS R5s要来了,很可能具备像素位移功能

一向以慢著称的佳能奋发图强&#xff0c;推新机的速度整个就是下饺子的节奏&#xff01;2020年一季度将推出EOS R5S&#xff01;一般佳能说到S就是高像素&#xff0c;R5S也不例外&#xff0c;不过像素高了视频功能就别太期待的了。1、像素全画幅 9000万像素2、像素位移功能可拍…

ForkJoin、普通方法、stream并行流计算对比

1.什么是ForkJoin? orkJoin 在 JDK 1.7 &#xff0c; 并行执行任务&#xff01;提高效率。大数据量&#xff01; 大数据&#xff1a;Map Reduce &#xff08;把大任务拆分为小任务&#xff09; 2.ForkJoin特点 工作窃取&#xff0c;这个里面维护的都是双端队列 3.ForkJoin结…

异步回调,用一个例子带你起飞!

1.Future接口 Future 设计的初衷&#xff1a; 对将来的某个事件的结果进行建模 异步回调&#xff1a; 这里基本不怎么直接使用future&#xff0c;而是使用它的一个实现类CompletableFuture,这个类的很多方法都是加强了的&#xff0c;比较怕常用。 2.CompletableFuture类 接下…

vb6反编译详解_[原创]VB6反编译详解(一)

[原创]VB6反编译详解(一)2006-7-9 16:5923171[原创]VB6反编译详解(一)2006-7-9 16:5923171VB6反编译详解 by Kenmark-Fenix**************************************************最新于2006-7-13更新&#xff01;**************************************************写本文已经惦…

就算错过,也不进来看看?volatile保证可见性、非原子性以及避免指令重排(内存屏障)详解

一.JMM–Java内存模型 *1.什么是JMM&#xff1f; JMM &#xff1a; Java内存模型&#xff0c;不存在的东西&#xff0c;是一种概念&#xff01;是一种约定&#xff01; *2.关于JMM的一些同步的约定&#xff1a; 1、线程解锁前&#xff0c;必须把共享变量立刻刷回主存。 2、…

linux怎样自制库_Linux 库的制作--动态库与静态库

Linux 库的制作1.动态库 xxx.so2.静态库 xxx.a相同点:库中都有一组实现好的函数接口不同点:如果我们连接的是动态库&#xff0c;此时只是在可执行文件的头信息中记录动态库的名字&#xff0c;具体函数的实现代码并没有存放在可执行文件中&#xff0c;所以在可执行文件执行的时候…