暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

多线程实现按顺序循环输出ABC

盛超杰的笔记 2018-11-02
215

题目

今天一个朋友问了我一个题目,A,B,C三个线程,按照顺序,依次循环输出A,B,C字符。思路我大概是知道的,但是从来没实践过,既然是别人提出技术问题,那么我肯定是在所不辞的。

思路

让多线程之间按照顺序输出,那么可以考虑用锁控制对应顺序,B等待A释放锁,C等待B释放锁,我们的选择可以有CountDownLatch和CyclicBarrier,但是有循环的条件,所以应该选择可以重置的CyclicBarrier。 之后的思考就是如何通过CyclicBarrier实现C执行完后再执行A。

我的代码如下

  1. public static void main(String[] args) {

  2.        final CyclicBarrier cyclicBarrier2 = new CyclicBarrier(2);

  3.        final CyclicBarrier cyclicBarrier3 = new CyclicBarrier(2);

  4.        final CyclicBarrier cyclicBarrier4 = new CyclicBarrier(3);


  5.        Thread threadA = new Thread(new Runnable() {

  6.            @Override

  7.            public void run() {

  8.                try {

  9.                    while(true) {

  10.                        System.out.println("A");

  11.                        //控制A执行完在执行

  12.                        cyclicBarrier2.await();

  13.                        //等待ABC都运行完

  14.                        cyclicBarrier4.await();

  15.                    }

  16.                }catch (Exception ex){

  17.                    ex.printStackTrace();

  18.                }

  19.            }

  20.        });


  21.        Thread threadB = new Thread(new Runnable() {

  22.            @Override

  23.            public void run() {

  24.                try {

  25.                    while(true) {

  26.                        cyclicBarrier2.await();

  27.                        System.out.println("B");

  28.                        //控制B执行完在执行C

  29.                        cyclicBarrier3.await();

  30.                        //等待ABC都运行完

  31.                        cyclicBarrier4.await();

  32.                    }

  33.                }catch (Exception ex){

  34.                    ex.printStackTrace();

  35.                }

  36.            }

  37.        });


  38.        Thread threadC = new Thread(new Runnable() {

  39.            @Override

  40.            public void run() {

  41.                try {

  42.                    while(true) {

  43.                        cyclicBarrier3.await();

  44.                        System.out.println("C");

  45.                        //等待ABC都运行完

  46.                        cyclicBarrier4.await();

  47.                    }

  48.                }catch (Exception ex){

  49.                    ex.printStackTrace();

  50.                }


  51.            }

  52.        });


  53.        threadC.start();

  54.        threadB.start();

  55.        threadA.start();



  56.    }

复制

对于CyclicBarrier需要注意一点,当打破屏障后,会自动重置,不需要手动调用它的reset方法(真是不试不知道)。

另外一种思路

使用SingleThreadExecutor能够保证线程顺序执行,其次每个线程执行完之后,再把自己放到线程池中去,那么就实现了循环。 按照题目的意思来讲,这个思路其实是不对的,因为实际上执行Runnable的线程都是同一个工作线程。哈哈哈。

  1. public static void main(String[] args) {

  2.        final ExecutorService executorService = Executors.newSingleThreadExecutor();


  3.        Runnable runnableA =new Runnable() {

  4.            @Override

  5.            public void run() {

  6.                System.out.println("A");

  7.                executorService.execute(this);

  8.            }

  9.        };



  10.        Runnable runnableB =new Runnable() {

  11.            @Override

  12.            public void run() {

  13.                System.out.println("A");

  14.                executorService.execute(this);

  15.            }

  16.        };



  17.        Runnable runnableC =new Runnable() {

  18.            @Override

  19.            public void run() {

  20.                System.out.println("A");

  21.                executorService.execute(this);

  22.            }

  23.        };


  24.        executorService.execute(runnableA);

  25.        executorService.execute(runnableB);

  26.        executorService.execute(runnableC);

  27.    }

复制

最后

还有什么实现方式呢。


文章转载自盛超杰的笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论