Java线程池ExecutorService和Executors应用(Spring Boot微服务)

记录:476

场景:在Spring Boot微服务中使用ExecutorService管理Java线程池。使用Executors创建线程池。使用Runnable接口实现类提交线程任务到线程池执行。

版本:JDK 1.8,Spring Boot 2.6.3。

1.线程和线程池基础

JDK自带线程和线程池包位置:java.util.concurrent.*,以及java.lang.Runnable和java.lang.Thread在java.lang.*中。

1.1线程接口Runnable

接口全称:java.lang.Runnable。

接口注释:The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread.

说明:提交给线程执行的类需实现Runnable接口。该接口只有一个抽象方法public abstract void run()。具体业务逻辑如需被线程调用的话,必须在此run方法内调用业务逻辑。

1.2线程Thread

类全称:java.lang.Thread。

类注释:A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.

说明:线程java.lang.Thread实现了java.lang.Runnable接口。在java.lang.Thread中维护了JVM中对线程的属性和方法的操作。方法包括线程创建、初始化、启动、运行、停止等。属性包括

线程名称、优先级、守护进程标志位、线程组、线程本地变量等。

接收Runnable线程任务方式:一般在创建Thread线程对象时,在有参构造函数的输入参数中传入自定义线程任务(实现Runnable接口的对象)。比如:public Thread(Runnable target)。

1.3线程池

(1)接口

java.util.concurrent.Executor,线程池顶层接口,只有一个抽象方法void execute(Runnable command)。此方法执行提交给线程池已实现Runnable接口的线程任务。

java.util.concurrent.ExecutorService,线程池接口,实现java.util.concurrent.Executor接口。此接口中主要提供线程池提交任务的submit方法、和invokeAll方法等方法。

(2)抽象类

java.util.concurrent.AbstractExecutorService,线程池默认实现方式,在AbstractExecutorService中提供默认的实现ExecutorService接口的方式。

(3)实现类

java.util.concurrent.ThreadPoolExecutor,线程池实现类。

主要是对线程池的创建、运行、维护等方面管理。

属性包括运行状态、线程池大小、线程池任务数量、线程池工厂类ThreadFactory、线程池工作线程、线程池同步线程锁、线程池任务队列BlockingQueue<Runnable> workQueue等。

方法包括一序列有参构造函数创建线程池、线程池执行任务方法void execute(Runnable command),以及获取线程池相关属性的get方法和设置线程池相关属性的set方法。

1.4线程池创建工具类Executors

全称:java.util.concurrent.Executors。

说明:在Executors中包括一序列创建线程池的静态方法,此类构造方法是private类型,因此不可被实例化。

类方法包括如下,可按需选择。

java 复制代码
public static ExecutorService newFixedThreadPool(int nThreads);
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory);
public static ExecutorService newWorkStealingPool();
public static ExecutorService newWorkStealingPool(int parallelism)
public static ExecutorService newSingleThreadExecutor();
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) ;
public static ExecutorService newCachedThreadPool();
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory);
public static ScheduledExecutorService newSingleThreadScheduledExecutor();
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);

1.5其它

(1)线程专用的一些类

java.lang.Runnable

java.util.concurrent.Callable

java.util.concurrent.Future

java.util.concurrent.FutureTask

(2)线程工程类

线程池工厂(接口)

java.util.concurrent.ThreadFactory

线程池工厂(实现类)

java.util.concurrent.Executors.DefaultThreadFactory

java.util.concurrent.Executors.PrivilegedThreadFactory

(3)调度类线程体现

接口

java.util.concurrent.Executor

java.util.concurrent.ExecutorService

java.util.concurrent.ScheduledExecutorService

实现类

java.util.concurrent.ThreadPoolExecutor

实现类

java.util.concurrent.ScheduledThreadPoolExecutor

(4)其它

java.lang.SecurityManager

java.util.concurrent.ThreadPoolExecutor.Worker

2.使用Spring Boot注解配置线程池ExecutorService

(1)说明

ThreadPoolExecutor,全称:java.util.concurrent.ExecutorService。

使用@Bean("executorServiceHz")注解把线程池注入到Spring IOC容器中。

(2)代码

java 复制代码
@Configuration
public class ThreadPoolConfig {
  /**
   * 创建线程池
   */
  @Bean("executorServiceHz")
  public ExecutorService executorService() {
      ExecutorService executorService = Executors.newFixedThreadPool(8, new ThreadFactory() {
          @Override
          public Thread newThread(Runnable runnable) {
              return new Thread(runnable);
          }
      });
      return executorService;
  }
}

3.实现Runnable接口的线程任务类

(1)说明

提交给线程池任务,需实现Runnable接口。

Runnable接口的run方法里面就是线程具体执行的业务逻辑。

(2)代码

java 复制代码
public class SportContestExecutor implements Runnable {
    private TaskDto taskDto;
    public SportContestExecutor(TaskDto taskDto) {
        this.taskDto = taskDto;
    }
    @Override
    public void run() {
        String eventName = this.taskDto.getEventName();
        String content = this.taskDto.getContent();
        System.out.println("【线程: " + Thread.currentThread().getName() + ",在直播: " + eventName + content + "】");
    }
}

4.把实现Runnable接口的线程任务类提交到线程池

(1)说明

Runnable接口的线程任务类需提交到线程池才能具体执行。

(2)代码

java 复制代码
@Component("sportWorker02")
public class SportWorker02 {
  /**
   * 自动注入线程池
   */
  @Autowired
  private ExecutorService executorServiceHz;
  /**
   * 把线程任务提交到线程池
   */
  public void holdGame() {
  
      //1.准备数据
      List<TaskDto> groupStage = new ArrayList<>();
      for (int i = 0; i < 10; i++) {
          String no = "" + (i + 1);
          if (i < 9) {
              no = "0" + (i + 1);
          }
          TaskDto taskDto01 = TaskDto.builder().eventName("羽毛球球比赛").content("小组赛" + no).build();
          groupStage.add(taskDto01);
      }
      //2.线程任务提交到线程池
      for (TaskDto taskDto : groupStage) {
          executorServiceHz.execute(new SportContestExecutor(taskDto));
      }
  }
}

5.测试示例

(1)说明

直接在SpringBoot的启动类的main函数中测试。

在执行完成SpringApplication.run(Example212Application.class)后,SpringBoot的环境已经创建完成。

(2)代码

java 复制代码
@SpringBootApplication
public class Example212Application {
    public static void main(String[] args) {
        SpringApplication.run(Example212Application.class);
        SportWorker02 sportWorker02 = SpringUtil.getBean("sportWorker02");
        sportWorker02.holdGame();
    }
}

(3)输出结果

java 复制代码
【线程: Thread-5,在直播: 羽毛球球比赛小组赛02】
【线程: Thread-4,在直播: 羽毛球球比赛小组赛01】
【线程: Thread-6,在直播: 羽毛球球比赛小组赛03】
【线程: Thread-7,在直播: 羽毛球球比赛小组赛04】
【线程: Thread-8,在直播: 羽毛球球比赛小组赛05】
【线程: Thread-7,在直播: 羽毛球球比赛小组赛09】
【线程: Thread-5,在直播: 羽毛球球比赛小组赛10】
【线程: Thread-10,在直播: 羽毛球球比赛小组赛07】
【线程: Thread-9,在直播: 羽毛球球比赛小组赛06】
【线程: Thread-11,在直播: 羽毛球球比赛小组赛08】

6.辅助实体类

(1)说明

在实体类中使用注解@Data等来自lombok-1.18.24.jar。

(2)TaskDto

java 复制代码
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TaskDto implements Serializable {
    //赛事名称
    private String eventName;
    //活动内容
    private String content;
}

以上,感谢。

2023年9月14日

相关推荐
NE_STOP11 分钟前
SpringBoot--简单入门
java·spring
hqxstudying38 分钟前
Java创建型模式---原型模式
java·开发语言·设计模式·代码规范
Dcs1 小时前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java
保持学习ing1 小时前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
京东云开发者1 小时前
Java的SPI机制详解
java
超级小忍2 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
程序无bug2 小时前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享2 小时前
Java Lombok 入门
java
程序无bug2 小时前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队2 小时前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端