zoukankan      html  css  js  c++  java
  • 正确运用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

  • 相关阅读:
    批量导入
    循环语句
    判断循环常见
    常见C运算符
    oc将字符串中单词按照出现次数(次数都不一样)降序排序,排序之后单词只出现一次,源字符串中单词用下划线连接,生成字符串也用下滑线连接
    把字符串中的字母大小写反转OC
    查找子串出现次数OC
    现有一个数组NSMutableArray, 数组有若干个NSString的元素,进行选择法排序
    终端的一些命令
    编程语言名字来历
  • 原文地址:https://www.cnblogs.com/langtianya/p/5128958.html
Copyright © 2011-2022 走看看