线程池在项目的使用

791 阅读2分钟

是不是当了好久的程序员好久没写过线程的代码了,其实在日常开发中9线程的代码无处不在,只不过我们没有感受到.前几天在帮一个朋友梳理一个功能的逻辑时,最后写出来的代码执行时间是48s,这太慢了,因为数据库的量也挺大,而且他们建的表也十分恶心,那么只能对程序进行优化,他们的结果是生成报表,但是里边的树结构数据很多,只能循环遍历,那么第一步的优化先是吧循环一条一条查询的数据换成一次循环查出来一批数据,减少连接数据库的开销,然后这样优化到了20s左右,然后将固定不变的数据放到了缓存里边,这样优化到了8s,然后在项目中在for循环数据量最大的地方加入了多线程,使用线程池中的线程跑这一段for循环来组装数据,最后这一段代码被优化到了0.4s左右,也是我第一次在项目中使用线程池来操作业务,记录一下.下面写一个线程池在项目中使用的demo

@SpringBootTest
@RunWith(SpringRunner.class)
public class ThreadPoolTest{

    private static final int CORE_COUNT = Runtime.getRuntime().availableProcessors();
    
    @Test
    public void test1(){
        // 手动创建一个线程池 阿里巴巴规范推荐
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
            CORE_COUNT,
            CORE_COUNT * 8,
            10L,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1000),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
        
        // 现在执行两个异步任务,可以分开执行的任务,分具体业务使用
        CompletableFuture<Void> task1 = CompletableFuture.runAsync(()->{
               // 执行任务1具体逻辑代码,异步执行
               System.out.println("执行任务1代码");
        }, poolExecutor);
        
        CompletableFuture<Void> task2 = CompletableFuture.runAsync(()->{
               // 执行任务1具体逻辑代码,异步执行
               System.out.println("执行任务2代码");
        }, poolExecutor);
        
        // 等待上述的任务完成执行下边的代码
        CompletableFuture.allOf(task1, task2).get();
        
        // 关闭线程池
        poolExecutor.shutdown();
    }
}

除了用这种方法 还可以使用线程池和CountDownLatch结合使用,让主线程先等待,用其他线程去跑时间长的代码,跑完以后在执行主线程的代码,使用CountDownLatch的await方法就行.