【多线程】结合代码理解不同业务场景使用的多线程

实际开发中,有幸拜读公司中大佬写的代码,对于使用多线程的场景和实例可以很好的理解和加深对于多线程的全方位的理解,感谢大佬使我成长,特此记录下,好记性不如烂笔头Mark下

实际场景:当2个相同的场景依次需要对一数据处理时,若是串行,则使用的时间则是a+b,若是并行则使用的时间是max(a,b),并且防止过大的访问量导致oom,所以采用线程池的方式

一、通过线程池的submit方法进行处理多线程方法

  • submit() 该方法返回一个Future对象,可执行带返回值的线程;或者执行想随时可以取消的线程。Future对象的get()方法获取返回值。Future对象的cancel(true/false)取消任务,未开始或已完成返回false,参数表示是否中断执行中的线程
private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
            20,//corePoolSize 核心线程数
            50,//maximumPoolSize 最大线程数
            200,//空闲线程的最大存活时间
            TimeUnit.SECONDS,//上一个参数的单位
            new LinkedBlockingDeque<>(100000),//workQueue任务缓冲队列
            new ThreadPoolExecutor.CallerRunsPolicy()//兜底逻辑
    );

注意:线程池默认是无序的,若对顺序有严格要求,可使用单线程池(SingleThreadExecutor)或同步控制工具

单线程池:

通过 Executors.newSingleThreadExecutor() 创建的线程池会‌严格按提交顺序执行任务‌,因仅有一个工作线程

同步工具频繁阻塞性能可能很低,还是优先采用单线程池的方式:

CountDownLatch(闭锁/倒计时锁)用来进行线程同步协作,等待所有线程完成倒计时(一个或者多个线程,等待其他多个线程完成某件事情之后才能执行)

  • 其中构造参数用来初始化等待计数值

  • await() 用来等待计数归零

  • countDown() 用来让计数减一

CountDownLatch latchA = new CountDownLatch(1);
CountDownLatch latchB = new CountDownLatch(1);

pool.submit(() -> {
    System.out.println("Task A");
    latchA.countDown(); // 允许B启动
});

pool.submit(() -> {
    latchA.await();     // 等待A完成
    System.out.println("Task B");
    latchB.countDown(); // 允许C启动
});

pool.submit(() -> {
    latchB.await();     // 等待B完成
    System.out.println("Task C");
});

你可能感兴趣的:(技术-并发类,技术--开发类,多线程,threadPool,Executor,CountDownLatch)