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

java:线程池

目录

什么是线程池?

不使用线程池的问题

创建线程池

如何创建线程池对象?

方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。

什么时候开始创建临时线程?

什么时候拒绝策略?

方式二:通过Executors创建线程池。

Executors可能存在的陷阱


什么是线程池?

答:线程池就是一个可以复用线程的技术。

不使用线程池的问题

答:用户每次发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会影响系统的性能。

创建线程池

JDK5.0起提供了代表线程池的接口:ExecutorService.

如何创建线程池对象?

方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。

方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。(不推荐,后面会说)

方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepaliveTime,

TimeUnit unit,

BlockingQueue<Runnable>workQueue,

ThreadFactory thread Factory,

RejectedExecutionHandler)

使用指定的初始化参数创建一个新的线程池对象。

参数一:corePooLSize:指定线程池的核心线程的数量。

参数二:maximumPoolSize:指定线程池的最大线程数量。

参数三:keepAliveTime:指定临时线程的存活时间。

参数四:unit:指定临时线程存活或时间单位(秒,分,时,天)

参数五:workQueue:指定线程池的任务队列。

参数六:threadFactory:指定线程池的线程工厂。

参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满的时候,新任务就会拒绝)

package ExecutorServicedemo1;import java.util.concurrent.*;public class ExecutorServicedemo2 {public static void main(String[] args) {// 使用正确的构造函数签名创建线程池ExecutorService executorServices = new ThreadPoolExecutor(3, // 核心线程数5, // 最大线程数10, // 空闲线程存活时间TimeUnit.SECONDS, // 时间单位new ArrayBlockingQueue<>(3), // 任务队列Executors.defaultThreadFactory(), // 线程工厂new ThreadPoolExecutor.AbortPolicy() // 拒绝策略);MyRunnable myRunnable = new MyRunnable();executorServices.execute(myRunnable);executorServices.execute(myRunnable);executorServices.execute(myRunnable);Future<String> f1 = executorServices.submit(new MyCallable(10));try {System.out.println(f1.get());}catch (Exception e) {e.printStackTrace();}}
}
package ExecutorServicedemo1;public class MyRunnable implements Runnable{@Overridepublic void run(){for(int i = 0; i < 10; i++){System.out.println(Thread.currentThread().getName() + ": " + i);}}
}
package ExecutorServicedemo1;import java.util.concurrent.Callable;public class MyCallable implements Callable<String> {private int n;public MyCallable(int n) {this.n = n;}public String call() throws Exception {int sum = 0;for (int i = 0; i < n; i++) {sum += i;}return Thread.currentThread().getName() + ":" + sum;}
}

什么时候开始创建临时线程?

新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建线程。

什么时候拒绝策略?

核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。

通过Executors创建线程池

是一个线程池的工具类,提供了很多静态方法用来返回不同特点的线程池对象。

策略说明
ThreadPoolExecutor.AbortPolicy()丢弃任务并抛出RejectedExecutionExeception异常。是默认的策略
ThreadP0olExecutor.DisCardPolicy()丢弃任务,但是不抛出异常,这就是不推荐的做法。
ThreadPoolExecutor.DisCardOldstPolicy()抛弃队列中等待最久的任务,然后将当前任务加入队列中。
ThreadPoolExecutor.CallerRunsPolicy()由主线程负责任务的run()方法而绕过线程直接执行。

方式二:通过Executors创建线程池。

方法名称说明
public static ExecutorService newFixedThreadPool(int nThreads)创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程会补充一个新线程替代它。
public static ExecutorService newSingleThreadPool()

创建只有一个线程的线程池对象,

该线程出现异常而结束,那么线程池会补充一个新线程。

public static ExecutorService newCachedThreadPool()线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉。
public static  ScheduledExecutorService newScheduledThreadPool(int corePoolSize)创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。
 ExecutorService a= Executors.newFixedThreadPool(3);

Executors可能存在的陷阱

大型并发系环境中使用Executors去创建,如果不注意,可能会出现系统风险,而是通过ThreadPoolExecutor。


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

相关文章:

  • AI预测体彩排3采取888=3策略+和值012路或胆码测试9月3日升级新模型预测第71弹
  • Mysql(一) - 数据库操作, 表操作, CRUD
  • python使用selenium,实现简单爬虫功能
  • 什么是网络准入控制系统?四款网络准入控制系统推荐 干货满满!
  • 在K8s上运行GitHub Actions的自托管运行器
  • 计算机网络——ARP篇
  • 让AI给你写代码(10.1): 按接口编程的思想,统一利用内部和外部的接口,逐步扩展和提升AI编程能力
  • Azure和Transformers的详细解释
  • FastAPI 中间件与依赖注入:打造灵活的 API 架构
  • Web前端全栈Vue3项目实战:‌从零到一的完整指南
  • 仕考网:事业单位考试分为哪几种类型?
  • Python | Pandas中有效处理大数据集的6种方法
  • 赛题解读!文心智能体大赛招募中
  • 【深度学习 GPU显卡】英伟达Tesla系列显卡:深度学习领域的强大动力
  • 图片损坏,如何修复?
  • 剪画:新手自媒体人必备技能:视频基础剪辑!
  • strings.NewReader 、reader.Read(buf) 的介绍
  • 图形语言传输格式glTF和三维瓦片数据3Dtiles(b3dm、pnts)学习
  • 惠海H6922升压 升降压 IC 3.7V 5V 7.4V 12V升压12v24v48v60v200W大功率风扇电机供电
  • day47——面向对象特征之继承