0
点赞
收藏
分享

微信扫一扫

多任务AB并行与C串行



文章目录

  • 前言
  • 三种方案
  • 1.利用join
  • 2.利用线程计数器CountDownLatch
  • 3.利用park实现
  • 总结


前言

多任务执行的时候,有时候有这样的场景,就是有三个事件 ABC,AB执行顺序无所谓,但是C一定要在AB执行之后,再执行;

例如: 计算 1+ 2 =3;
先获取1 和 2 的顺序无所谓,可以并行
但是计算等于3的时候,一定要在 1 2 之后;

三种方案

1.利用join

多线程执行的情况下, join 可以保证一个线程执行完;
代码如下(示例):

public class AB并行后Join执行C {

    @SneakyThrows
    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {

            Thread a = new Thread(() -> {
                System.out.println("A");
            });
            a.start();
            Thread b = new Thread(() -> {
                System.out.println("B");
            });
            b.start();

            a.join();
            b.join();
            new Thread(() -> {
                System.out.println("C");
            }).start();
        }

    }
}

2.利用线程计数器CountDownLatch

多线程执行下,计数器可以保证多线程之间的信息同步;

public class AB并行后执行C {

    public static void main(String[] args) {

        CountDownLatch countDownLatch = new CountDownLatch(2);

        new Thread(() -> {
            System.out.println("A");
            countDownLatch.countDown();
        }).start();
        new Thread(() -> {
            System.out.println("B");
            countDownLatch.countDown();
        }).start();

        new Thread(() -> {
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("C");
        }).start();
    }
}

3.利用park实现

LockSupport中的park() 和unpark()可以实现上述场景,但是需要借助计数器,这里使用原子类实现;

public class AB并行后park执行C {

    public static void main(String[] args) {


        for (int i = 0; i < 10; i++) {
            AtomicInteger atomicInteger = new AtomicInteger(2);

            Thread c = new Thread(() -> {
                LockSupport.park();
                System.out.println("C");
            });
            c.start();

            new Thread(() -> {
                System.out.println("A");
                while (atomicInteger.decrementAndGet() == 0) {
                    LockSupport.unpark(c);
                }
            }).start();
            new Thread(() -> {
                System.out.println("B");
                while (atomicInteger.decrementAndGet() == 0) {
                    LockSupport.unpark(c);
                }
            }).start();
        }
    }
}

总结

其实这里实现的方案大同小异,但是比较推荐后两种;
思路都是通过线程之间通信,完成并行之后的串行;


举报

相关推荐

0 条评论