Java多线程之线程池详解

素颜马尾好姑娘i 2022-05-15 14:06 452阅读 0赞

线程池概念

存放多个线程对象的资源池
用于提高启动多个线程的性能(类比连接池)
当程序中涉及创建大量生存期很短的线程,推荐使用线程池。

内置线程池

  1. SingleThreadPool:创建一个单线程化的线程池,只有唯一一个线程来执行任务,保证所有任务按照指定顺序执行(可能是先进先出,后进先出,优先级别)
  2. FixedThreadPool:创建可以可以重用的固定数量的线程池。
  3. CachedThreadPool:创建一个根据需要可新增线程的线程池。
  4. ScheduledThreadPool:创建一个定长的线程池,支持定时及周期性任务调度。

线程池源码简单解析

线程池类的层次图:
在这里插入图片描述

Executor:顶层接口,接受线程任务并且执行
在这里插入图片描述
ExecutorService:添加了一些其他方法。ThreadPoolExecutor:添加了一些常规的线程池,Single,Fixed,Cached
在这里插入图片描述
或许有的同学觉得这几参数比较难理解所以我这给出一个简化版本

  1. corePoolSize - 核心线程数
  2. maximumPoolSize - 最大线程数。
  3. keepAliveTime - 线程存活时间
  4. unit -时间单位设置
  5. keepAliveTime-任务缓存队列

Executor:工具类,创建不同的线程池。
ScheduleThreadPoolExecutor:调度的线程池

线程池的简单应用

SingleThreadPool

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. public class ThreadPoolTest01 {
  4. public static void main(String[] args) {
  5. //创建SingleThreadPool线程池
  6. ExecutorService pool = Executors.newSingleThreadExecutor();
  7. //创建FixedThreadPool线程池,并且定义为3个线程的线程池
  8. ExecutorService pool = Executors.newFixedThreadPool(3);
  9. //创建CachedThreadPool线程池
  10. ExecutorService pool = Executors.newCachedThreadPool();
  11. //创建很多个任务
  12. TaskTest t1 = new TaskTest("t1");//创建任务1
  13. TaskTest t2 = new TaskTest("t2");//创建任务2
  14. TaskTest t3 = new TaskTest("t3");//创建任务3
  15. TaskTest t4 = new TaskTest("t4");//创建任务4
  16. TaskTest t5 = new TaskTest("t5");//创建任务5
  17. pool.execute(t1);//执行t1
  18. pool.execute(t2);//执行t2
  19. pool.execute(t3);//执行t3
  20. pool.execute(t4);//执行t4
  21. pool.execute(t5);//执行t5
  22. pool.shutdown();//关闭
  23. }
  24. }
  25. class TaskTest implements Runnable{
  26. private String name; //任务名字
  27. public TaskTest(String name) {
  28. this.name = name;
  29. }
  30. @Override
  31. public void run() {
  32. // TODO Auto-generated method stub
  33. System.out.println(Thread.currentThread().getName()+"正在执行"+name);
  34. }
  35. }

SingleThreadPool运行结果 在这里插入图片描述
可以看出,所有任务都是由线程1来完成的,满足只有唯一一个线程来执行任务,保证所有任务按照指定顺序执行。

FixedThreadPool运行结果:
在这里插入图片描述
满足所有线程都由创建的三个线程来完成

CachedThreadPool运行结果:
在这里插入图片描述
满足线程的增加

调度线程池

  1. import java.util.concurrent.ScheduledThreadPoolExecutor;
  2. import java.util.concurrent.TimeUnit;
  3. public class ScheduledExecutorTest02 {
  4. public static void main(String[] args) {
  5. SET t1 = new SET("t1");
  6. SET t2 = new SET("t2");
  7. //创建有两个线程的调度线程池
  8. ScheduledThreadPoolExecutor sche = new ScheduledThreadPoolExecutor(2);
  9. sche.scheduleAtFixedRate(t1,1,1,TimeUnit.SECONDS);//设置t1调度参数
  10. sche.scheduleAtFixedRate(t2,1,1,TimeUnit.SECONDS);//设置t2调度参数
  11. }
  12. }
  13. class SET implements Runnable{
  14. private String name; //任务名字
  15. public SET(String name) {
  16. this.name = name;
  17. }
  18. @Override
  19. public void run() {
  20. // TODO Auto-generated method stub
  21. System.out.println(Thread.currentThread().getName()+"正在执行"+name);
  22. }
  23. }

运行结果
在这里插入图片描述

问题:调度线程池中的线程是否跟任务绑定,还是到调度时间,重新分配?
回答:通过上图画红线得出答案,是到调度时间重新分配。

发表评论

表情:
评论列表 (有 0 条评论,452人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java线线

    java多线程之线程池 池化技术 程序的运行,其本质上,是对系统资源(CPU、内存、磁盘、网络等等)的使用。如何高效的使用这些资源是我们编程优化演进的一个方向。今天说

    相关 线线

    前言: 1. 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时,