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。

  • 相关阅读:
    LeetCode Array Easy 1. Two Sum
    关于VS2015 发布.net mvc 网站失败的问题
    2016计蒜之道复赛 百度地图的实时路况 floyd+cdq分治
    2016计蒜之道复赛 菜鸟物流的运输网络 网络流EK
    HDU5715 XOR 游戏 二分+字典树+dp
    HDU5697 刷题计划 dp+最小乘积生成树
    codeforces 687D Dividing Kingdom II 带权并查集(dsu)
    codeforces 687C
    codeforces 687B
    HDU 5693 D Game 区间dp
  • 原文地址:https://www.cnblogs.com/AK47Sonic/p/7705584.html
Copyright © 2011-2022 走看看