正确运用synchronized和二次判断 实现多线程安全

正确运用synchronized和二次判断 实现多线程安全,做出高效二符合预期的程序,特别是多个线程跑一个对象的时候,如下图所示: 
在此输入图片描述

测试代码如下: 
特别注意if(shutdownRequested){ *部分不同的写法。

不然就会输出与逻辑不符的现象: 
如:

runner—-false—-我没有关闭。。。

runner—-true—-我没有关闭。。。

runner—-true—-我关闭了=====»>


package com.xue.gang.volatiler;

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class VolatileRunner{

public static void main(String args[]) throws InterruptedException {

    int size=1000;

    CountDownLatch countDownLatch = new CountDownLatch(size);
    TomRunner tomRunner = new TomRunner(false,countDownLatch,"runner");
    ExecutorService executorService = Executors.newCachedThreadPool();

    for(int i=1;i<=size;i++){
        executorService.execute(new Thread2RunTomRunner(countDownLatch,tomRunner,i+"_号"));
    }
    countDownLatch.await();
    executorService.shutdown();
    //new Thread(volatileRunner).start();
}

static class Thread2RunTomRunner implements Runnable{
    private CountDownLatch  countDownLatch;
    private TomRunner tomRunner;
    private String name;

    public Thread2RunTomRunner(CountDownLatch countDownLatch,
            TomRunner tomRunner, String name) {
        super();
        this.countDownLatch = countDownLatch;
        this.tomRunner = tomRunner;
        this.name = name;
    }

    public void run() {
        System.out.println(this.name+":running...");
        this.tomRunner.doWork();
        System.out.println(this.name+":结束...");
        this.countDownLatch.countDown();

    }
}
static class TomRunner{

    volatile boolean shutdownRequested = false;
    //boolean shutdownRequested = false;
    String name;

    public TomRunner(boolean shutdownRequested,
            CountDownLatch countDownLatch, String name) {
        super();
        this.shutdownRequested = shutdownRequested;

        this.name = name;
    }

    public void shutdown() {
        this.shutdownRequested = true;
    }
    public void doWork() {
        while (true) {

            /**
             *多个线程的代码去执行:  System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
             * */
               /*if(shutdownRequested){
                    System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
                    break;
                }else{
                    System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
                    shutdown();
                }*/
            /**
             * 如果没有二次判断,也会出现比较脏数据.
             * */
            /*
                if(shutdownRequested){
                    System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
                    break;
                }
                synchronized (this) {
                    System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
                    shutdown();
                }*/
            /**
             * 加上二次判断,能够正确
             * */

            if(shutdownRequested){
                System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我关闭了=====>>>");
                break;
            }
                synchronized (this) {
                if(!shutdownRequested){
                    System.out.println(this.name + "----" + this.shutdownRequested +"----" +"我没有关闭。。。");
                    shutdown();
                }
            }           
        }
    }
}

}

原:http://my.oschina.net/u/177808/blog/165442

原文地址:https://www.cnblogs.com/langtianya/p/5128958.html