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

江西移动网站沭阳建设局网站

江西移动网站,沭阳建设局网站,网站区域名怎么注册吗,广东省网络推广公司目录 线程池 为什么使用线程池 线程池的使用 工厂类Executors(工厂模式) submit 实现一个线程池 线程池 为什么使用线程池 在前面我们都是通过new Thread() 来创建线程的,虽然在java中对线程的创建、中断、销毁、等值等功能提供了支持…

目录

线程池

为什么使用线程池

线程池的使用

工厂类Executors(工厂模式)

submit 

实现一个线程池


线程池

为什么使用线程池

在前面我们都是通过new Thread() 来创建线程的,虽然在java中对线程的创建、中断、销毁、等值等功能提供了支持,一个线程的创建和销毁虽然消耗虽然小,但从操作系统角度来看,如果我们频繁的创建和销毁线程,是需要大量的时间和资源的,那么有没有什么开销更小的方法?

第一种是协程,它可以说是轻量级线程,但是java很少用,多用于go和python。

第二种是线程池,java中多用线程池去解决频繁的创建和销毁线程问题。

那么为啥引入线程池就能够提升效率呢?

1.直接创建/销毁线程,是需要在用户态+内核态配合完成的工作,对于线程池,只需要在用户态即可,不需要内核态的配合,这样开销就更小

2.等线程用完之后,线程池不会销毁该线程,而是让其阻塞,等下次用的时候会再次利用它,所以不用频繁的进行创建和销毁。

线程池最核心的设计思路:复用线程,平摊线程的创建与销毁的开销代价

线程池的使用

java 提供了多种方式来创建线程池,主要通过Executors(执行者)工厂类或直接使ThreadPoolExecutor类来完成

工厂类Executors(工厂模式)

使用Executors工厂类:

newFixedThreadPool(int nThreads):创建一个固定大小的线程池,线程数量由nThreads参数确定。
newCachedThreadPool():创建一个线程数量为动态的线程池,线程数量会根据任务数量动态变化,当长时间没有新任务时,空闲线程会被终止。

newSingleThreadExecutor():创建一个单线程的线程池,它只会创建一个线程来执行任务。
newScheduledThreadPool(int corePoolSize):创建一个可以安排任务的线程池,可以指定延迟执行任务或定期执行任务。

后面两个我们用的都不多,主要是用前面两个

下面是使用代码:

​
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {// 创建一个固定大小的线程池ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);// 创建一个可缓存的线程池(线程数量动态调整)ExecutorService cachedThreadPool = Executors.newCachedThreadPool();}
}

这代码我们有个疑点,我们并没有new一个对象,那我们是怎么创建出来对象的呢?

这个问题涉及到工厂模式这种设计模式:

工厂模式是一种常用的设计模式,用于封装对象的创建逻辑。它通过使用方法来创建对象(new在方法内部),而不是直接使用 new 关键字实例化对象。这样可以将对象的创建逻辑与使用逻辑解耦,提高代码的可维护性和可扩展性。

这里就是用方法创建出对象,所以涉及到了工厂模式

ThreadPoolExecutor类(直接new)
对于刚才讲的 Executors 本质上是 ThreadPoolExecutor 类的封装.         

而对于ThreadPoolExecutor类本身我们提供了更多的可选参数, 可以进一步细化线程池行为的设定. 

如下图是 ThreadPoolExecutor类的构造方法:

核心线程数(corePoolSize):线程池中始终保持的线程数量。这是不会被销毁的。

最大线程数(maximumPoolSize):线程池中允许的最大线程数量。这种一般涉及到刚才的动态线程池,如果任务多了则创建一些线程,多了的话过了一段时间则会销毁,但核心线程数不变。

空闲线程存活时间(keepAliveTime):当线程池中的线程数量超过核心线程数时,空闲线程的存活时间。

任务队列(workQueue):其为阻塞队列,用于存储等待执行的任务。要记住,当我们创建线程池时,系统也会同时自动创建一个阻塞队列去存储等待执行的任务,这样效率就更高。

线程工厂(threadFactory):线程工厂是一个用于创建线程的工具类或接口,它允许用户自定义线程的创建逻辑,开发者可以控制线程的名称、优先级、异常处理等属性,从而更好地管理线程资源。

拒绝策略(handler):当线程池已满且阻塞队列也已满时,新任务的处理策略。

下面重点讲述一下拒绝策略:

  • AbortPolicy:直接抛出 RejectedExecutionException 异常。(当导员给我一个任务“统计班级成员中团员个数‘’,但是我现在已经课很多了,我一下子就哭了出来)这个就相当于直接抛异常
  • CallerRunsPolicy:由提交任务的线程直接执行任务。(我直接给导员说,我没空,导员最后只能自己做了)
  • DiscardPolicy:直接丢弃任务,不抛出异常。(导员一听我没空,就直接说,好!那我也不统计了,随便来了)
  • DiscardOldestPolicy:丢弃队列中最老的任务,然后尝试提交新任务。(我听到导员的任务的时候,我选择放弃我最早出现的一节课去帮导员完成任务)

下面是其创建代码 

 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,  // 核心线程数4,  // 最大线程数60,  // 空闲线程存活时间TimeUnit.SECONDS,  // 时间单位new ArrayBlockingQueue<>(10),  // 任务队列,容量为 10Executors.defaultThreadFactory(),  // 线程工厂new ThreadPoolExecutor.AbortPolicy()  // 拒绝策略);

总结一下:

  • 工厂模式创建线程:适合简单的线程池创建场景,代码简单,但灵活性有限。

  • 构造方法创建线程:适合需要灵活配置线程池属性的场景,通过自定义线程池,可以更好地管理线程资源,提高代码的可维护性和可扩展性。

submit 

 通过线程池.submit(继承runable的类的对象) 可以提交一个任务到线程池中执行.

ExecutorService pool = Executors.newFixedThreadPool(10);
pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}
});
实现一个线程池

 这里就直接上代码了,不多说,重点还是使用线程池,不是实现线程池。

/*** 自定义线程池执行器类* 该类通过实现一个具有固定大小的线程池和一个阻塞队列来管理线程,用于异步执行任务*/
class MyThreadPoolExecutor {// 创建阻塞队列,用于存放待执行的任务// 队列大小设为1000,用于控制并发任务的数量,避免过多任务导致资源耗尽BlockingQueue<Runnable>  blockingQueue=new ArrayBlockingQueue<>(1000);/*** 构造函数,初始化线程池* 创建一个线程,该线程循环从阻塞队列中取任务并执行* 这个线程是线程池中的工作线程,负责执行提交的任务*/public MyThreadPoolExecutor(int n) {for (int i = 1; i <= n; i++) {Thread t = new Thread(() -> {// 无限循环,确保线程池可以持续处理任务,直到程序中断或阻塞队列被清空while (true) {try {// 从阻塞队列中取出一个任务,如果队列为空,则线程被阻塞,直到有任务放入队列Runnable task = blockingQueue.take();// 执行取出的任务task.run();} catch (InterruptedException e) {// 如果线程在等待状态时被中断,抛出运行时异常// 这通常会导致程序异常终止throw new RuntimeException(e);}}});// 启动线程池中的工作线程t.start();}}/*** 提交一个任务到线程池* @param task 需要被执行的任务*            任务被放入阻塞队列中,随后由线程池中的工作线程执行*/public void submit(Runnable task){// 将任务放入阻塞队列,如果队列已满,则操作会阻塞,直到有空间可用blockingQueue.offer(task);}
}
class DemoTest1{public static void main(String[] args) throws InterruptedException {MyThreadPoolExecutor ex=new MyThreadPoolExecutor(4);for(int i=0;i<100;i++) {int id = i;ex.submit(()->{System.out.println(Thread.currentThread().getName()+"  任务:"+id);});}}
}

多线程基础知识点到这里就告一段路了,接下来我们将学习多线程(进阶)这部分是主要讲面试中经典题,频繁的题

http://www.dtcms.com/a/418014.html

相关文章:

  • 长宁网站制作设计网站页面设计
  • 织梦cms通用蓝白简介大气企业网站环保科技公司源码网站建设报告心得体会
  • 免费网站推广渠道wordpress安全防范教程
  • 提供邯郸做wap网站不属于企业网站建设基本标准的是
  • 饰品做商城网站模式学服装设计后悔死了
  • 网站建设公司 合肥电子商务网站建设合同书
  • 自己网站做反链seo推广的网站和平台有哪些
  • 大同网站建设哪家好100个创意营销广告语
  • 做轮播海报的网站删除wordpress缓存文件在哪
  • 临沂做网站公司哪家好上海网站建设安全
  • 网站连锁店查询怎么做网络广告弹性指的是什么
  • 怀柔网站建设wordpress鼠标停留
  • 做汉字的教育网站重庆网站建设重庆零臻科技行
  • 北京首钢建设有限公司网站基金网站制作
  • dedecms企业网站模板门窗卫浴网站建设
  • 如何开发自己公司的网站网络营销外包的优点
  • 网站二次开发公司企业网站的价值
  • 用模板做网站网站建设的书 豆瓣
  • 网站建设开票写什么网站建设竞争性磋商文件
  • 电影网站膜拜助君网络怎么样
  • 包头网站作风建设年自评材料网站建设的主题
  • 用什么来网站开发好wordpress阿里百秀模板下载
  • 大好网站网站开发 activex
  • 做神马网站优化快速排软件技术专升本可以报什么专业
  • 留号码的广告网站中国小说网站策划与建设
  • it软件网站建设找装修活上哪个平台
  • 百度收录了我新网站的2篇文章了湖南省住建云公共信息服务平台
  • 做网站的哪家好网站收录平台方法
  • 陕西建设网综合便民服务中心网站制作公司网站设计要求
  • 做推手需要开网站吗黄冈公司做网站