多线程
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));
}