使用CountDownLatch模拟指令重排

来源:互联网 发布:行业报告 知乎 编辑:程序博客网 时间:2024/05/26 22:05

      • 使用CountDownLatch模拟指令重排
      • 使用CyclicBarrier模拟指令重排

1. 使用CountDownLatch模拟指令重排

import java.util.concurrent.CountDownLatch;/** * @author mnmlist@163.com * @date 2017/05/18 * @time 16:29 */public class InstructionsRearrangement {    public static void main(String[] args) {        int threadCount = 1024 * 1024 * 100;        for(int i=0; i<threadCount; i++) {            final Example example = new Example();      // 用来控制线程同时执行某些语句同时执行的锁            CountDownLatch mutexCountDownLatch = new CountDownLatch(1);      //在此例子中没有明确的作用,类似thread.join(),起阻塞作用            CountDownLatch threadCountDownLatch = new CountDownLatch(2);            new Thread(new ReaderThreadDemo(example, mutexCountDownLatch, threadCountDownLatch)).start();            new Thread(new WriterThreadDemo(example, mutexCountDownLatch, threadCountDownLatch)).start();            // 触发线程中同时执行mutexCountDownLatch.await()后的语句,用来模拟同时执行            // 线程中的某些语句            mutexCountDownLatch.countDown();            try {                threadCountDownLatch.await();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}class WriterThreadDemo implements Runnable {    private Example example;    private CountDownLatch mutexCountDownLatch;    private CountDownLatch threadCountDownLatch;    public WriterThreadDemo(Example example, CountDownLatch mutexCountDownLatch,            CountDownLatch threadCountDownLath) {        this.example = example;        this.mutexCountDownLatch = mutexCountDownLatch;        this.threadCountDownLatch = threadCountDownLath;    }    public void run() {        try {            // 所有的线程阻塞在此位置,执行mutexCountDownLatch.countDown()后所有的线程            // 从该语句后的语句开始执行,用来模拟不同的线程同时执行相应的语句            mutexCountDownLatch.await();            example.writer();        } catch (InterruptedException e) {            e.printStackTrace();        }finally {            threadCountDownLatch.countDown();        }    }}class ReaderThreadDemo implements Runnable {    private Example example;    private CountDownLatch mutexCountDownLatch;    private CountDownLatch threadCountDownLatch;    public ReaderThreadDemo(Example example, CountDownLatch mutexCountDownLatch,            CountDownLatch threadCountDownLath) {        this.example = example;        this.mutexCountDownLatch = mutexCountDownLatch;        this.threadCountDownLatch = threadCountDownLath;    }    public void run() {        try {            mutexCountDownLatch.await();            example.reader();        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            threadCountDownLatch.countDown();        }    }}class Example {    int a = 0;    boolean flag = false;    public void writer() {        a = 100; //1        flag = true; //2    }    public void reader() {        // 本来flag的赋值在a=0的后面,通常情况下如果flag==true时a==100,        // 如果flag已经被赋值且a还是原来的值则表明先执行了flag=true,指令发生了重排序        //在本例中,发生指令重排序的时候会输出It happends        if (flag) { //3            if(0 == a) {                System.out.println("It happens");            }        }    }}

结果如图所示:
指令重排结果

2. 使用CyclicBarrier模拟指令重排

import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * @author mnmlist@163.com * @date 2017/05/21 * @time 10:59 */public class CyclicBarrierDemo {    public static void main(String[] args) {        int threadCount = 1024 * 1024 * 100;        for(int i=0; i<threadCount; i++) {            Example example = new Example();            // 内存屏障,当所有的线程都到达该屏障时然后再继续执行屏障后的语句            CyclicBarrier cyclicBarrier = new CyclicBarrier(2);            Thread t2 = new Thread(new ReaderDemo(cyclicBarrier, example));            Thread t1 = new Thread(new WriterDemo(cyclicBarrier, example));            t1.start();            t2.start();            try {                t1.join();                t2.join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}class WriterDemo implements Runnable {    private CyclicBarrier cyclicBarrier;    private Example example;    public WriterDemo(CyclicBarrier cyclicBarrier, Example example) {        this.cyclicBarrier = cyclicBarrier;        this.example = example;    }    public void run() {        try {            //阻塞在这里            cyclicBarrier.await();              example.writer();        } catch (InterruptedException e) {            e.printStackTrace();        } catch (BrokenBarrierException e) {            e.printStackTrace();        }    }}class ReaderDemo implements Runnable {    private CyclicBarrier cyclicBarrier;    private Example example;    public ReaderDemo(CyclicBarrier cyclicBarrier, Example example) {        this.cyclicBarrier = cyclicBarrier;        this.example = example;    }    public void run() {        try {            //阻塞在这里            cyclicBarrier.await();            example.reader();        } catch (InterruptedException e) {            e.printStackTrace();        } catch (BrokenBarrierException e) {            e.printStackTrace();        }    }}