Skip to content
鼓励作者:欢迎打赏犒劳

多线程

spring中使用线程池

java
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

@Configuration
public class ExecutorServiceConfig {
     private static final Integer CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
    @Bean
    @Qualifier("buyerPerformanceThreadPool")
    public ExecutorService buyerPerformanceThreadPool() {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("buyerPerformanceThreadPool-thread-%d").build();
    
        return new ThreadPoolExecutor(CORE_POOL_SIZE, CORE_POOL_SIZE * 2, 0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(1024 * 2), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                if (t != null) {
                    log.error("预警|buyerPerformanceThreadPool 线程运行异常", t);
                }
            }
        };
    }
}

多任务等待执行

awaitTermination实现

shutdown():停止接收新任务,原来的任务继续执行

shutdownNow():停止接收新任务,原来的任务停止执行

awaitTermination(long timeOut, TimeUnit unit):当前线程阻塞

当前线程阻塞,直到:

  • 等所有已提交的任务(包括正在跑的和队列中等待的)执行完;
  • 或者 等超时时间到了(timeout 和 TimeUnit设定的时间);
  • 或者 线程被中断,抛出InterruptedException
java
/**
 * awaitTermination 必须搭配 shutdown使用。如果没有shutdown,则会一直阻塞在awaitTermination方法上。
 * 如果线程池的方法都执行完了,则会返回true,否则返回false
 * @throws Exception
*/
@Test
public void test3() throws Exception {
    // 创建一个线程池对象
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    long a = System.currentTimeMillis();
    // 循环提交100个 SQL 查询任务给线程池
    for (int i = 1; i <= 10; i++) {
        int finalI = i;
        executorService.execute(() -> {
            int randomNumber = (int) (Math.random() * 100);
            System.out.println(finalI + "--开始" + "等待:" + randomNumber);
            try {
                Thread.sleep(randomNumber);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(finalI + "--执行完了");
        });
    }
    // 等待所有任务执行完成
    executorService.shutdown();
    boolean boo = executorService.awaitTermination(40, TimeUnit.MILLISECONDS);
    long b = System.currentTimeMillis();
    System.out.println( "总耗时:"+  (b-a) +",线程池是否完成:" + boo);
}

CountDownLatch实现

在主线程中,调用 CountDownLatch 的 await() 方法在所有 SQL 查询任务执行完成前阻塞线程,直到计数器减为 0 时,所有任务都已经执行完成可以继续往下执行,此时可以对查询结果进行汇总处理。

java
@Test
public void test3() throws Exception {
    int TASK_COUNT = 10;
    // 创建 CountDownLatch 对象
    CountDownLatch latch = new CountDownLatch(TASK_COUNT);
    long a = System.currentTimeMillis();
    // 创建线程池
    ExecutorService executorService = Executors.newFixedThreadPool(5);

    // 提交 SQL 查询任务
    for (int i = 1; i <= TASK_COUNT; i++) {
        int finalI = i;
        executorService.execute(() -> {
            int randomNumber = (int) (Math.random() * 100);
            System.out.println(finalI + "--开始" + "等待:" + randomNumber);
            try {
                Thread.sleep(randomNumber);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // CountDownLatch 计数器减 1
            latch.countDown();
            System.out.println(finalI + "--执行完了");
        });
    }

    // 等待所有任务执行完成
    latch.await();

    // 关闭线程池
    executorService.shutdown();
    long b = System.currentTimeMillis();
    System.out.println( "总耗时:"+  (b-a));
}

如有转载或 CV 的请标注本站原文地址