iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >jdk线程池怎么实现
  • 215
分享到

jdk线程池怎么实现

2023-07-05 21:07:54 215人浏览 安东尼
摘要

本篇内容介绍了“jdk线程池怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!jdk线程池ThreadPoolExecutor的7个参数

本篇内容介绍了“jdk线程池怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

jdk线程池ThreadPoolExecutor的7个参数

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.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;    }

corePoolSize

核心线程个数 ,int类型

maximunPoolSize

最大线程数 ,int类型

keepAliveTime存活时间

传long类型的值,

当线程池中的线程数大于corePoolSize核心线程个数,且线程是闲置状态,则这些空闲线程的最大存活时间是KeepAliveTime

TimeUnit

存活时间的单位, 有时/分/秒/毫秒等可选配置

workQueue

存放待执行任务的阻塞队列, 可传入

arrayBlockingQueue 基于数组的有界阻塞队列;

linkedBlockingQueue基于链表的无界阻塞队列;

synchronousQueue最多只有1个元素的同步队列, 队列容量是1;

priorityBlockingQueue带优先级的无界阻塞队列,出队元素是优先级最高或最低的元素;

DelayQueue 带延迟功能的无界阻塞队列, 过期元素才会出队,队头元素是快要过期的元素.

以上几个Queue都是BlockingQueue的实现类

threadFactory

创建线程的工厂,

jdk提供了DefaultThreadFactory默认工厂,

用Executors.defaultThreadFactory()就行.

RejectedExecutionHandler拒绝策略

当队列满且线程数达到maximunPoolSize最大线程数后采取的策略, 可传入

AbortPolicy 抛出异常,这个是默认策略.

CallersRunPolicy 由调用者所在的线程执行任务

DiscardOldestPolicy 丢弃最老的任务

DiscardPolicy 丢弃新任务,不抛出异常

jdk提供的Executors快速创建线程池的用法

jdk封装了一个Executors类可以直接创建各种线程池,

用法形如

ExecutorService pool = Executors.newXXXXXPool()

可以用Executors类创建业务常用的3种线程池

固定线程池

public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }

创建一个核心线程数和最大线程数相同的线程池,都为nThreads,

且线程池的阻塞队列长度是Integer.MAX_VALUE,

且keepAliveTime=0,说明只要线程个数比核心线程个数多并且当前空闲则回收.

单线程线程池

public static ExecutorService newSingleThreadExecutor() {        return new FinalizableDelegatedExecutorService            (new ThreadPoolExecutor(1, 1,                                    0L, TimeUnit.MILLISECONDS,                                    new LinkedBlockingQueue<Runnable>()));    }

创建一个核心线程数和最大线程数都是1的线程池,

且线程池的阻塞队列长度是Integer.MAX_VALUE,

且keepAliveTime=0,说明只要线程个数比核心线程个数多并且当前空闲则回收.

缓存的线程池

public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>());    }

创建一个按需创建线程的线程池,初始线程个数为0,最多线程个数为

Integer.MAX_VALUE,并且阻塞队列为同步队列.

keepAliveTime=60,说明当前线程在60s内空闲则回收.

CachedThreadPool的特殊之处在于,加入同步队列的任务会被马上执行,同步队列里边最多只有1个任务.

使用创建好的ExecutorService 线程池执行异步任务

jdk线程池怎么实现

submit操作

提交一个任务, 任务参数可以是 Runnable实现类 或 Callable 实现类.

返回的类型是Future 表示异步计算的结果, 可以用future.get()方法拿到数据.

shutdown操作

调用shutdown方法后,线程池就不会再接受新的任务了,但是工作队列里边的任务还是要执行的, 该方法会立刻返回,不等待队列任务完成再返回.

使用线程池的情况下当程序结束时记得调用shutdown关闭线程池, 如果不关闭线程池,则会导致 线程池资源一直不被释放.

shutdownNow操作

调用shutdownNow方法后,线程池就不会再接受新的任务了,并且会丢弃工作队列里边的任务,正在执行的任务会被中断,该方法会立刻返回,并不等待激活的任务执行完成. 返回值为这时候队列里面被丢弃的任务列表.

awaitTermination操作

当线程调用awaitTermination方法后,当前线程会被阻塞, 直到线程池状态变为TERMINATED 才返回,或者等待时间超时才返回.

案例1-测试FixedThreadPool执行CallableTask任务

package cn.demo;import cn.hutool.core.util.RandomUtil;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class ExecutorTestsForCallableTask {    public static void main(String[] args) throws ExecutionException, InterruptedException {        String res1 = "";        String res2 = "";        String res3 = "";        String res4 = "";        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);        //submit 提交4个任务, 实际执行时,任务是并发执行的,执行顺序不固定        Future<String> submit1 = fixedThreadPool.submit(                new TestCallableTask(RandomUtil.randomInt(30,1000),"t1"));        Future<String> submit2 = fixedThreadPool.submit(                new TestCallableTask(RandomUtil.randomInt(100,400),"t2"));        Future<String> submit3 = fixedThreadPool.submit(                new TestCallableTask(RandomUtil.randomInt(30,350),"t3"));        Future<String> submit4 = fixedThreadPool.submit(                new TestCallableTask(RandomUtil.randomInt(310,500),"t4"));        res1 = submit1.get();        System.out.println(res1);        res2 = submit2.get();        System.out.println(res2);        res3 = submit3.get();        System.out.println(res3);        res4 = submit4.get();        System.out.println(res4);        fixedThreadPool.shutdown();    }}
package cn.demo;import cn.hutool.core.util.RandomUtil;import java.time.LocalDateTime;import java.util.concurrent.Callable;public class TestCallableTask implements Callable<String> {    private int testIntVal;    private String taskSeq;    public TestCallableTask(int testIntVal, String taskSeq) {        this.testIntVal = testIntVal;        this.taskSeq = taskSeq;    }    @Override    public  String call() throws Exception {        String s = LocalDateTime.now().toString();        System.out.println(s+"->"+taskSeq+" run ....");        int i = testIntVal;        System.out.println(i);        try {            Thread.sleep(RandomUtil.randomInt(100,300));        } catch (InterruptedException e) {            e.printStackTrace();        }        if (i>300){            return "300more";        }else {            return "300less";        }    }}

案例2-测试FixedThreadPool执行RunnableTask任务

package cn.demo;import java.util.concurrent.*;public class ExecutorTestsForRunnableTask {    public static void main(String[] args) throws ExecutionException, InterruptedException {        String res1 = "";        String res2 = "";        String res3 = "";        String res4 = "";        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);        //submit 提交4个任务, 实际执行时,任务是并发执行的,执行顺序不固定        Task1Param task1Param = new Task1Param();        task1Param.setUrl("f23r3r");        task1Param.setName("1heg43t34t34t");        Future<String> stringFuture = fixedThreadPool.submit(            new TestTask1Runnable(task1Param), "success1 ok");        Task1Param t2 = new Task1Param();        t2.setUrl("gnsg2323");        t2.setName("2wwswer2r1asdaaws");        Future<String> f2 = fixedThreadPool.submit(new TestTask1Runnable(t2), "success2 ok");        Task1Param t3 = new Task1Param();        t3.setUrl("thwasr23r");        t3.setName("3erzawfe23rawsf");        Future<String> f3 = fixedThreadPool.submit(new TestTask1Runnable(t3), "success3 ok");        Task1Param t4 = new Task1Param();        t4.setUrl("mjkdsragt");        t4.setName("4tbertydraewrsfk");        Future<String> f4 = fixedThreadPool.submit(new TestTask1Runnable(t4), "success4 ok");        res1 = stringFuture.get();        System.out.println(res1);        res2 = f2.get();        System.out.println(res2);        res3 = f3.get();        System.out.println(res3);        res4 = f4.get();        System.out.println(res4);        fixedThreadPool.shutdown();    }}
package cn.demo;import cn.hutool.core.util.RandomUtil;import java.time.LocalDateTime;public class TestTask1Runnable implements Runnable{    private Task1Param task1Param;    public TestTask1Runnable(Task1Param task1Param) {        this.task1Param = task1Param;    }    @Override    public void run() {        try {            Thread.sleep(RandomUtil.randomInt(200,600));        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(task1Param.getName());        System.out.println(task1Param.getUrl());        String s = LocalDateTime.now().toString();        System.out.println(s+" TestTask1Runnable run ....");    }}

使用自定义的ThreadPoolExecutor来执行异步任务

package cn.demo;import cn.hutool.core.util.RandomUtil;import java.util.concurrent.*;public class TpeTest {    private final static ThreadPoolExecutor pool =            new ThreadPoolExecutor(                    1,1,                    1L, TimeUnit.MINUTES,                    new ArrayBlockingQueue<Runnable>(1),                    new ThreadPoolExecutor.CallerRunsPolicy());    public static void main(String[] args) throws ExecutionException, InterruptedException {        Future<String> submit1 = pool.submit(                new TestCallableTask(RandomUtil.randomInt(30,1000),"t1"));        Future<String> submit2 = pool.submit(                new TestCallableTask(RandomUtil.randomInt(100,400),"t2"));        Future<String> submit3 = pool.submit(                new TestCallableTask(RandomUtil.randomInt(30,350),"t3"));        Future<String> submit4 = pool.submit(                new TestCallableTask(RandomUtil.randomInt(310,500),"t4"));        System.out.println("task1-"+submit1.get());        System.out.println("task2-"+submit2.get());        System.out.println("task3-"+submit3.get());        System.out.println("task4-"+submit4.get());        pool.shutdown();    }}

线程池使用FutureTask时需要注意的事情

线程池使用FutureTask时,如果把拒绝策略设置为 DiscardPolicy 和 DiscardOldestPolicy,并且在被拒绝的任务的Future对象上调用了无参get方法,那么调用线程会一直被阻塞.

如上面的代码,如果把CallerRunsPolicy替换成 DiscardPolicy 或 DiscardOldestPolicy ,就会导致任务一直被阻塞,一直无法取到future.get()的值.

“jdk线程池怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: jdk线程池怎么实现

本文链接: https://www.lsjlt.com/news/355515.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • jdk线程池怎么实现
    本篇内容介绍了“jdk线程池怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!jdk线程池ThreadPoolExecutor的7个参数...
    99+
    2023-07-05
  • jdk线程池的实现
    jdk线程池ThreadPoolExecutor的7个参数 public ThreadPoolExecutor(int corePoolSize, ...
    99+
    2023-05-14
    jdk线程池
  • Java手写线程池之向JDK线程池进发
    目录前言JDK线程池一瞥自己动手实现线程池线程池参数介绍实现Runnable实现Callable拒绝策略的实现线程池关闭实现工作线程的工作实现线程池实现的BUG完整代码线程池测试总结...
    99+
    2022-11-13
    Java手写线程池 Java线程池
  • golang怎么实现线程池
    在Golang中,可以使用goroutine和channel来实现线程池。下面是一个简单的示例: package main imp...
    99+
    2023-10-21
    golang
  • golang线程池怎么实现
    在Go语言中,可以使用`goroutine`和`channel`来实现线程池。下面是一个简单的线程池实现示例: package ma...
    99+
    2023-10-27
    golang
  • Tomcat修正JDK原生线程池bug的实现原理
    为提高处理能力和并发度,Web容器一般会把处理请求的任务放到线程池,而JDK的原生线程池先天适合CPU密集型任务,于是Tomcat改造之。 Tomcat 线程池原理 其实Thread...
    99+
    2024-04-02
  • Springboot自带线程池怎么实现
    本篇文章和大家了解一下Springboot自带线程池怎么实现。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。一: ThreadPoolTaskExecuto1 ThreadPoolTaskExecutor线程池:Threa...
    99+
    2023-07-06
  • SpringBoot实现线程池
    现在由于系统越来越复杂,导致很多接口速度变慢,这时候就会想到可以利用线程池来处理一些耗时并不影响系统的操作。 新建Spring Boot项目 1. ExecutorConfig....
    99+
    2024-04-02
  • python实现线程池
    什么是线程池?     诸如web服务器、数据库服务器、文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务。构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就创建一个新的服务对象,然后在新的服务对象中...
    99+
    2023-01-31
    线程 python
  • java中怎么实现一个线程池
    本篇文章为大家展示了java中怎么实现一个线程池,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。有些人可能对线程池比较陌生,并且更不熟悉线程池的工作原理。所以他们在使用线程的时候,多数情况下都是new...
    99+
    2023-06-20
  • GOworkPool的线程池实现
    Go语言中的线程池是一种用于管理并发执行任务的设计模式。 线程池的主要目的是减少创建和销毁线程的开销,提高系统性能。 在Go语言中,线程池通常使用goroutine和channel来...
    99+
    2023-03-24
    GO workPool线程池 GO workPool
  • 怎么使用Node实现轻量化进程池和线程池
    今天小编给大家分享一下怎么使用Node实现轻量化进程池和线程池的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们...
    99+
    2024-04-02
  • Java简单实现线程池
    本文实例为大家分享了Java简单实现线程池的具体代码,供大家参考,具体内容如下 一、线程池 线程池是一种缓冲提高效率的技术。 相当于一个池子,里面存放大量已经创建好的线程,当有一个任...
    99+
    2024-04-02
  • C++线程池实现代码
    前言 这段时间看了《C++并发编程实战》的基础内容,想着利用最近学的知识自己实现一个简单的线程池。 什么是线程池 线程池(thread pool)是一种线程使用模式。线程过多或者频繁...
    99+
    2024-04-02
  • 用 Python 实现的线程池
    为了提高程序的效率,经常要用到多线程,尤其是IO等需要等待外部响应的部分。线程的创建、销毁和调度本身是有代价的,如果一个线程的任务相对简单,那这些时间和空间开销就不容忽视了,此时用线程池就是更好的选择,即创建一些线程然后反复利用它们,而不...
    99+
    2023-01-31
    线程 Python
  • SpringBoot线程池和Java线程池怎么使用
    这篇文章主要介绍“SpringBoot线程池和Java线程池怎么使用”,在日常操作中,相信很多人在SpringBoot线程池和Java线程池怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringB...
    99+
    2023-07-06
  • JavaEE线程安全实现线程池方法
    前言: 线程虽然比进程更轻量,但是如果创建销毁的频率进一步增加,开销还是很大 解决方案:线程池or协程 线程池:把线程提前创建好放到池子里,后续用到线程直接从池子里取不必这边申请了。...
    99+
    2024-04-02
  • Java线程池的构造方法怎么实现
    本篇内容主要讲解“Java线程池的构造方法怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java线程池的构造方法怎么实现”吧!一、 前言为了实现并发编程,于是就引入了进程这个概念。进程就...
    99+
    2023-06-29
  • Java怎么实现手写线程池并测试
    本篇内容介绍了“Java怎么实现手写线程池并测试”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!线程池的核心流程:在线程池核心原理的源码中,涉...
    99+
    2023-07-05
  • C++怎么实现一个简单的线程池
    本文小编为大家详细介绍“C++怎么实现一个简单的线程池”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++怎么实现一个简单的线程池”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、设计线程池应该包括保存线程的容...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作