java创建线程池代码_java手写线程池

java创建线程池代码_java手写线程池oracle提供了一个通过ThreadPoolExecutor创建一个线程池的类构造器使用给定的参数和默认的饱和策略、默认的工厂方法创建线程池ThreadPoolExecutor(intcorePoolSize,intmaximumPoolSize,longkeepAliveTime,TimeUnitunit,BlockingQueue<Runna…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

jdk提供了一个通过ThreadPoolExecutor创建一个线程池的类

构造器

使用给定的参数和默认的饱和策略、默认的工厂方法创建线程池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)

使用给定的参数和默认的工厂方法创建线程池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue, 
RejectedExecutionHandler handler)

使用给定的参数和默认的饱和策略(AbortPolicy)创建线程池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize,
long keepAliveTime,
BlockingQueue<Runnable> workQueue, 
ThreadFactory threadFactory)

使用指定的参数创建线程池

ThreadPoolExecutor(int corePoolSize, 
int maximumPoolSize, 
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue, 
RejectedExecutionHandler handler)

参数说明

  • corePoolSize 线程池的基本大小, 当提交一个任务到线程池的时候,线程池会创建一个线程来执行任务,即使当前线程池已经存在空闲线程,仍然会创建一个线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有的基本线程。
  • maximumPoolSizeSize 线程池最大数量,线程池允许创建的最大线程数,如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是,如果使用了无界的任务队列这个参数就没什么效果。
  • keepAliveTime 线程活动保持时间,线程池的工作线程空闲后,保持存活的时间,所以,如果任务很多,并且每个任务执行的时间比较短,可以调大时间,提高线程的利用率。
  • unit 线程活动保持时间的单位,可选择的单位有时分秒等等。
  • workQueue 任务队列。用来暂时保存任务的工作队列
  • threadFactory 用于创建线程的工厂

队列

  • ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按照FIFO(先进先出)原则对元素进行排序
  • DelayQueue
  • LinkedBlockingDeque
  • LinkedBlockingQueue:是一个基于链表结构的有界阻塞队列,此队列按照FIFO排序元素,吞吐量高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool(n)使用了此队列
  • LinkedTransferQueue
  • PriorityBlockingQueue:一个具有优先级的无限阻塞队列
  • SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等待另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool()使用了此队列

饱和策略

当队列和线程池都满了,说明线程池处于饱和的状态,那么必须采取一种策略处理提交的新任务。这个策略默认是AbortPolicy,表示无法处理新任务时抛出异常

  • ThreadPoolExecutor.AbortPolicy:直接抛出异常
  • ThreadPoolExecutor.CallerRunsPolicy:只用调用这所在的线程来运行任务
  • ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
  • ThreadPoolExecutor.DiscardPolicy:不处理,丢弃掉

示例

public class ThreadPool { 
   

    /** * 线程池的基本大小 */
    static int corePoolSize = 10;
    /** * 线程池最大数量 */
    static int maximumPoolSizeSize = 100;
    /** * 线程活动保持时间 */
    static long keepAliveTime = 1;
    /** * 任务队列 */
    static ArrayBlockingQueue workQueue = new ArrayBlockingQueue(10);

    public static void main(String[] args) { 
   
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSizeSize,
                keepAliveTime,
                TimeUnit.SECONDS,
                workQueue,
                new ThreadFactoryBuilder().setNameFormat("XX-task-%d").build());
        //提交一个任务
        executor.execute(() -> System.out.println("ok"));
    }
}

源码分析

任务执行

public void execute(Runnable command) { 
   
        if (command == null)
            throw new NullPointerException();
        /* * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. * * 2. If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. * * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. */
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) { 
   
            if (addWorker(command, true))
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) { 
   
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }

参考文档

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187339.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Python中的多线程「建议收藏」

    Python中的多线程「建议收藏」什么是多线程:进程:正在运行的程序,QQ360……线程:就是进程中一条执行程序的执行路径,一个程序至少有一条执行路径。(360中的杀毒电脑体检电脑清理同时运行的话就需要开启多条路

    2022年7月3日
    33
  • 普林斯顿公开课 算法1-5:算法理论

    普林斯顿公开课 算法1-5:算法理论

    2021年11月16日
    43
  • 后端框架flask学习小记[通俗易懂]

    后端框架flask学习小记[通俗易懂]1.写在前面最近在和几个伙伴尝试搭建一个新闻推荐系统,算是一个推荐算法的实战项目,里面涉及到了前后端交互,该项目里面,使用了Flask作为后台框架,为了理清楚整个系统的交互,所以就快速参考着资料学习了下flask,主要还是参考伙伴们写的flask简介和基础的内容,加上了一些其他理解和实验辅助,整理一篇心得文章,算是flask初步入门。对于一个算法工程师来讲,后端这块虽然不必详细弄清楚原理,但学习一些开发相关知识还是有好处的,因为在实际工作中经常会调试线上的代码调用策略或者模型,我们至少

    2022年6月6日
    56
  • MyBatis-延迟加载与MyBatis缓存(面试题)

    MyBatis-延迟加载与MyBatis缓存(面试题)MyBatis-延迟加载与MyBatis缓存-概念性MyBatis-延迟加载与MyBatis缓存MyBatis-延迟加载与MyBatis缓存-概念性延迟加载(面试题)1、什么是延迟加载(按需加载)2、延迟加载MyBatis缓存(面试题)1、Cache缓存2、MyBatis缓存分析3、一级缓存4、二级缓存原理开启二级缓存5、禁用二级缓存6、刷新二级缓存延迟加载(面试题)1、什么是延迟加载(按需…

    2022年5月21日
    34
  • 平行四边形符号怎么打出来_几何画板如何打平行四边形符号

    平行四边形符号怎么打出来_几何画板如何打平行四边形符号平行四边形符号是两组对边平行的四边形,平行四边形符号有两种,空心和实心“▰▱”。 ▱ ▰ ◇ ◆ 平行四边形符号怎么打?1、在QQ聊天窗口中,按住Alt键别松开,然后在数字键区依次按9649松开Alt键就是“▱”,同理按9648就是平行四边形符号“▰”。2、在Word或Execl中画出平行四边形,点击“…

    2022年4月19日
    113
  • pycharm2019.3.3激活教程_pycharm2020.2激活码

    pycharm2019.3.3激活教程_pycharm2020.2激活码下载官网下载2019.03最新版http://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows安装一路点击下一步,安装目录建议放在非C盘位置激活方式1:激活码第一次打开时,激活方式选择激活码。复制粘贴下面一整行,点击激活即可。有效期是2019年11月份,到时候会更新新的激活码。这种方式…

    2022年8月25日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号