多线程之按序打印

174 阅读2分钟






  这道题是典型的设置执行屏障的问题,要确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行,对于这道问题的解法我可以直接定义一个变量variable,三个线程分别去监控variable值,当variable=0的时候执行第一个方法,variable=1的时候执行第二个方法,variable=2的时候执行第三个方法。



  当variable的值被修改时,其他线程应该要马上能知道variable值的变化,才能做出判断执不执行本身方法,所以variable变量要用volatile关键字修饰来保证线程之间的可见性,比如variable初始值为0,线程A执行方法一,执行完方法一之后把variable的值加1此时variable的值变成了1,由于variable变量用了volatile来修饰,所以线程B马上就能知道variable的值变为了1,所以此时线程B就会调用方法二....

代码如下:

class Foo {
     public Foo() {            }    private volatile int variable=0;    public void first(Runnable printFirst) throws InterruptedException {        printFirst.run();        variable++;    }
    public void second(Runnable printSecond) throws InterruptedException {        while (true){            if(variable==1) break;        }        printSecond.run();        variable++;    }
    public void third(Runnable printThird) throws InterruptedException {         while (true){            if(variable==2) break;        }        printThird.run();    }}

Leecode上提交结果:





  CountDownLatch能够使一个线程等待其他线程完成各自的工作后再执行,这样子我们可以让线程B等待线程A执行完成之后再执行,线程C等待线程B执行完成之后再执行就可以实现按序打印了。

  CountDownLatch通过构造函数构造一个计数器来实现,计数器的数值即为为线程的数量,每当一个线程完成了自己的任务后,计数器的值就会减1,计数器值为0时,表示CountDownLatch里面所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。具体实现看代码注释。

代码如下:

class Foo {
     public Foo() {            }   private CountDownLatch a = new CountDownLatch(1);  //信号量a   private CountDownLatch b = new CountDownLatch(1);  //信号量b
    public void first(Runnable printFirst) throws InterruptedException {        printFirst.run();        a.countDown(); //信号量a计数器减1, 计数器变为0,表示信号量a执行完。    }
    public void second(Runnable printSecond) throws InterruptedException {        a.await(); //等待信息量a的线程执行完        printSecond.run();        b.countDown();  //信号量b减一,计数器变为0,表示信号量b执行完。    }
    public void third(Runnable printThird) throws InterruptedException {        b.await();//等待信号量b的线程执行完        printThird.run();    }}

LeeCode运行结果: