当前位置: 首页 > news >正文

线程池是啥有啥用,怎么用,如何自己实现一个

目录

一、线程池是啥,有啥用

二、线程池怎么用 

1.构造方法 

2.如何使用Java的线程池  

三、简单实现一个线程池


假设我是一个(好看+有才华) 的妹子,那么我就会有很多追求者,这些也叫备胎们,我们若把他们放到一个地方,那就叫“备胎池”。同理,线程就叫“线程池”。

一、线程池是啥,有啥用

频繁的创建销毁线程开销太大,所以我们会先创建一些线程放着,要用的时候直接拿就行了,这些线程都放一块地方,用完之后再放回这个地方,那么我们管这个地方叫“线程池”。

 所以:线程池最⼤的好处就是减少每次启动、销毁线程的损耗。

 

那么为什么线程池的效率更高,开销更小呢? 

 那么就得谈谈:用户态和内核态

比如说:

1)在银行你要办业务,可能会需要身份证或者户口本复印件,这时候,你如果没带,那么银行可能会有复印机。

2)那么你有2种选择:第一种是去柜台让柜员帮你,第二种是自己去大厅的复印机复印。

3)内核态:如果让柜员帮你去后台复印,可能没这么快,柜员也许要帮别人也复印,也可能去摸鱼,也可能去上个厕所。我们知道操作系统是由内核和软件组成,有很多软件都需要内核管理,可能会没那么及时。

4)用户态:如果你是自己去大厅复印,自给自足,非常的快。

5)而我们的线程池就是用户态,自己创建线程是内核态,所以效率会比线程池低。

二、线程池怎么用 

 我们有专门的类表示线程池:ThreadPoolExecutor

1.构造方法 

下面是它的构造方法,最主要的是第4个最为全面,其他三个都是从第4个演化出来的。

 我们分析一下这个线程池的参数:

  • corePoolSize:正式员⼯的数量. (正式员⼯, ⼀旦录⽤, 永不辞退)
  • maximumPoolSize: 正式员⼯ + 临时⼯的数⽬. (临时⼯: ⼀段时间不⼲活, 就被辞退)
  • keepAliveTime: 临时⼯允许的空闲时间
  • unit: keepaliveTime 的时间单位, 是秒, 分钟, 还是其他值
  • workQueue: 传递任务的阻塞队列
  • threadFactory: 创建线程的⼯⼚, 参与具体的创建线程⼯作,通过不同线程⼯⼚创建出的线程相当于 对⼀些属性进⾏了不同的初始化设置
  • RejectedExecutionHandler: 拒绝策略, 如果任务量超出公司的负荷了接下来怎么处理 
    1. AbortPolicy(): 超过负荷, 直接抛出异常          
    2. CallerRunsPolicy(): 调⽤者负责处理多出来的任务     
    3. DiscardOldestPolicy(): 丢弃队列中最⽼的任务
    4. DiscardPolicy(): 丢弃新来的任务  

1)corePoolSize和maximumPoolSize中,如果核心线程数是M个,在使用的过程中发现不够用,会自动扩容多M个,直至最大线程数max个。

 2)keepAliveTime和unit是姐妹,一起用的,就是实习生(非核心线程)太久没活干了,就会裁掉它,怎么样才算太久呢?就需要你自己设置一个时间

3)workQueue是我们需要传进去的堵塞队列,线程池就是一个生产者消费者模型,程序员把任务submit放进线程池中。这个队列可以自己设计容量和类型。

4)线程工厂,是为了弥补构造方法的不足,比如假设我在二维中需要表示一个点,我有2种方法,第一种是横纵坐标,第二种是用极坐标,

但是这样的话重载就失效了,因为名字参数什么的啥都一样啊,构成不了重载。

而是需要工厂设计模式解决,如上图。

5)拒绝策略(重点):当线程池的要执行的任务满了,它就会进行堵塞。但是有时候这未必是件好事。比如说你女神直接拒绝你,比起干耗着你好,这样你就能开启新的生活了。

假设线程池是女神,你是任务,但是备胎太多了忙不过来。

第一个就是女神拒绝了你,你崩溃了,其他备胎也崩溃了(没想到女神有这么多备胎);

第二个女神不想你追她,让你去追其他小姐姐,但是女神依旧和备胎们约会;

第三个是把追的最久的备胎扔掉,没新鲜感了,和最新追我的约会;

第四个是把最新的备胎踢掉,是个念旧的女神,就当一切没有发生,继续和之前的备胎们约会。

2.如何使用Java的线程池  

虽然ThreadPoolExecutor固然强大,但是参数太多,用起来确实麻烦,所以Java标准库中有更方便的:Executor提供了一些工厂方法,比如:

接受线程池的类型:ExecutorService

创建便捷线程池的方法:newFixedThreadPool(),把核心线程数和最大线程数设置成一样,不会自动扩容

添加任务到线程池执行:submit() 

public static void main(String[] args) throws InterruptedException {ExecutorService service=Executors.newFixedThreadPool(4);for(int i=0;i<100;i++){int id=i;service.submit(()->{Thread current=Thread.currentThread();System.out.println("hello world "+id+ " "+current.getName());});}Thread.sleep(2000);service.shutdown();System.out.println("程序结束");}

三、简单实现一个线程池

需要如下条件:

一个堵塞队列queue,来装要执行的任务,通过take取任务。

线程池类,来用for循环放线程(相当于线程池),这个类有submit()方法用queue队列中用put就能放进去执行这些线程中。

(由于拒绝策略太麻烦了,这里没有写出来,感兴趣的可以自行写一下)

class MyThreadPool {private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(1000);//创造线程public MyThreadPool(int n) {for (int i = 0; i < n; i++) {Thread t = new Thread(() -> {while (true) {try {Runnable runnable=queue.take();runnable.run();} catch (InterruptedException e) {e.printStackTrace();}}});t.start();}}//创建任务public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}public class demo15 {public static void main(String[] args) throws InterruptedException {MyThreadPool myThreadPool=new MyThreadPool(4);for(int i=0;i<1000;i++){int id=i;myThreadPool.submit(()->{System.out.println("执行任务 "+id+" "+Thread.currentThread().getName());});}}}
  •  核⼼操作为 submit,将任务加⼊线程池中
  •  使⽤ Worker 类描述⼀个⼯作线程。使⽤ Runnable 描述⼀个任务.
  •  使⽤⼀个 BlockingQueue 组织所有的任务
  •  每个 worker 线程要做的事情:不停的从 BlockingQueue 中取任务并执⾏
  •  指定⼀下线程池中的最⼤线程数 maxWorkerCount;当当前线程数超过这个最⼤值时,就不再新增线程了

http://www.mrgr.cn/news/28450.html

相关文章:

  • Liebherr利勃海尔 EDI 需求分析
  • DHTMLX-gantt组件显示不同的颜色
  • 一键抠图:免费安全的在线图片去除背景工具
  • Python数据分析NumPy和pandas(二十九、其他Python可视化工具)
  • uniapp如何i18n国际化
  • MQ集群
  • 接口测试(十二)
  • 【网络】TCP/IP 五层网络模型:数据链路层
  • 速盾:怎么使用cdn加速视频?
  • c++ templates常用函数
  • 进口车电子信息单二维码解密
  • react hooks--useLayoutEffect
  • Python pdf转换为html
  • vmvare如何给centos7 设置静态IP地址
  • 计算机的错误计算(九十五)
  • 【C++学习入门】6.左值右值
  • 探索人工智能的未来趋势
  • 24.9.16数据结构|平衡二叉树
  • [项目][WebServer][Makefile Shell]详细讲解
  • 机器学习的入门指南
  • re题(22)BUUFCTF-[ACTF新生赛2020]rome
  • 速盾:cdn免备案免费加速?
  • Spring为什么要用三级缓存解决循环依赖?
  • Robot Operating System——带有协方差矩阵的线速度和角速度
  • 世界排名第一的数码照片和图形放大软件PhotoZoom Pro 9
  • 【ShuQiHere】 进位回补与溢出问题全解:二补码与一补码的进阶指南