zoukankan      html  css  js  c++  java
  • Java 学习笔记之 实例变量非线程安全

    实例变量非线程安全:

    如果多个线程共同访问1个对象中的实例变量,则可能出现“非线程安全”问题。

    public class UnSafeHasSelfPrivateNum {
        private int num = 0;
        public void addI(String username) {
            try {
                if (username.equals("a")){
                    num = 100;
                    System.out.println("a set over!");
                    Thread.sleep(2000);
                } else {
                    num = 200;
                    System.out.println("b set over!");
                }
                System.out.println(username + " num = " + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class UnSafeHasSelfPrivateNumThreadA extends Thread{
        private UnSafeHasSelfPrivateNum numRef;
    
        public UnSafeHasSelfPrivateNumThreadA(UnSafeHasSelfPrivateNum numRef) {
            this.numRef = numRef;
        }
    
        @Override
        public void run() {
            super.run();
            numRef.addI("a");
        }
    }
    
    public class UnSafeHasSelfPrivateNumThreadB extends Thread {
        private UnSafeHasSelfPrivateNum numRef;
    
        public UnSafeHasSelfPrivateNumThreadB(UnSafeHasSelfPrivateNum numRef) {
            this.numRef = numRef;
        }
    
        @Override
        public void run() {
            super.run();
            numRef.addI("b");
        }
    }
    
    public class ThreadRunMain {
        public static void main(String[] args) {
            testUnSafeHasSelfPrivateNumThread();
        }
    
        public static void testUnSafeHasSelfPrivateNumThread(){
            UnSafeHasSelfPrivateNum numRef = new UnSafeHasSelfPrivateNum();
            UnSafeHasSelfPrivateNumThreadA athread = new UnSafeHasSelfPrivateNumThreadA(numRef);
            athread.start();
            UnSafeHasSelfPrivateNumThreadB bthread = new UnSafeHasSelfPrivateNumThreadB(numRef);
            bthread.start();
        }
    }

    运行结果:

    a的值本应该是100,却变成了200. 用synchronized关键字解决问题:

    public class UnSafeHasSelfPrivateNum {
        private int num = 0;
        synchronized public void addI(String username) {
            try {
                if (username.equals("a")){
                    num = 100;
                    System.out.println("a set over!");
                    Thread.sleep(2000);
                } else {
                    num = 200;
                    System.out.println("b set over!");
                }
                System.out.println(username + " num = " + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    运行结果:

    在两个线程访问同一个对象中的同步方法时是线程安全的,先执行a,在执行b。

  • 相关阅读:
    Castle 开发系列文章
    ASP.NET MVC 3 Release Candidate 发布喽
    Scott Hanselman on SpeakerWiki
    2010年上半年计算机软考软件设计师试卷参考答案
    一站式示例代码库2010年11月5日更新
    从数据到代码—基于T4的代码生成方式
    CodeDOM
    老吉优秀的数据库访问层代码(转)
    非关语言: 设计模式
    EntLib
  • 原文地址:https://www.cnblogs.com/AK47Sonic/p/7705584.html
Copyright © 2011-2022 走看看