• leetCode例题引出的多线程CountDownLatch和CyclicBarrier使用例题


    先介绍下CountDownLatch和CyclicBarrier;

    CountDownLatchnew CountDownLatch(n),初始化时会赋值,并且不可以重新赋值。

                                  countDown(),值减1,操作,当值为0时,会跳过所有的阻塞方法await();

                                  await(),阻塞方法,一直阻塞到值为0;

    CyclicBarrier:new CyclicBarrier(m),m代表着,每次阻拦的阈值,当阻拦的await方法的个数等于m时,所有的阻塞方法则会跳过。然后开始阻塞下一批线程,每批数量为m。

                            await(),阻塞方法,每次阻塞的格式为m。

    题目1115:

    我们提供一个类:

    class FooBar {
      public void foo() {
        for (int i = 0; i < n; i++) {
          print("foo");
        }
      }
    
      public void bar() {
        for (int i = 0; i < n; i++) {
          print("bar");
        }
      }
    }

    两个不同的线程将会共用一个 FooBar 实例。其中一个线程将会调用 foo() 方法,另一个线程将会调用 bar() 方法。
    请设计修改程序,以确保 "foobar" 被输出 n 次。

    线上最受赞答案:

     1 import java.util.concurrent.CountDownLatch;
     2 import java.util.concurrent.CyclicBarrier;
     3 
     4 public class FooBar{
     5       private int n;
     6       private CountDownLatch countDownLatch;  //countDownLatch只能复制一次,在值为0时,await()才会执行完毕
     7       private CyclicBarrier cyclicBarrier;    //cyclicBarrier可以复制多次,值为每组多少个成员。
     8 
     9       public FooBar(int n){
    10           this.n=n;
    11           countDownLatch = new CountDownLatch(1);   
    12           cyclicBarrier = new CyclicBarrier(2);   //每组两个成员
    13       }
    14 
    15       public void foo(Runnable printFoo) throws InterruptedException {
    16           try{
    17               for (int i=0;i<n;i++){
    18                   printFoo.run();     //打印foo
    19                   countDownLatch.countDown();  //打印完后,其中值变为0,28行阻塞开始跳过,打印bar
    20                   cyclicBarrier.await();    //阻塞,等阻塞的线程为2时,跳过改方法
    21               }
    22           } catch (Exception e){}
    23       }
    24 
    25     public void bar(Runnable printBar) throws InterruptedException {
    26         try{
    27             for (int i=0;i<n;i++){
    28                 countDownLatch.await();  //阻塞,确保先打印foo
    29                 printBar.run();    //打印bar
    30                 countDownLatch = new CountDownLatch(1);  //为打印下一组foobar做准备
    31                 cyclicBarrier.await();  //阻塞,等阻塞的线程为2时,跳过改方法
    32             }
    33         } catch (Exception e){}
    34     }
    35 
    36 }
  • 相关阅读:
    Python面向对象编程
    Python模块
    Python函数式编程(把函数作为参数传入)
    Python函数高级特性
    Python函数基础
    连续数字或英文字符文本强制换行
    flex布局文本过长不显示省略号
    在div中放一个相同大小的svg,实际显示的位置svg偏下
    设置git push默认branch
    c# using
  • 原文地址:https://www.cnblogs.com/parent-absent-son/p/11913285.html
Copyright © 2020-2023  润新知