zoukankan      html  css  js  c++  java
  • java 多线程:线程安全问题synchronized关键字解决

    背景:

    多个线程同时修改一个变量时,有概率导致两次修改其中某些次被覆盖。

    例如:如下案例一个变量值为3,三个线程同时对其-1,如果按顺序执行,每次减完的结果应该是2,1,0。但实际运行中有可能变为0,0,0 ;0 1 1 等情况

    /**
     * @ClassName VarNotSafe
     * @projectName: object1
     * @author: Zhangmingda
     * @description: XXX
     * date: 2021/4/20.
     */
    public class VarNotSafe {
        public static int num = 3;
    
        public static void main(String[] args) {
            Runnable r = () -> {
                num--;
                System.out.println(Thread.currentThread().getName() + "结果==>:" + num);
            };
            Thread t1 = new Thread(r,"t1");
            Thread t2 = new Thread(r,"t2");
            Thread t3 = new Thread(r,"t3");
            t1.start();
            t2.start();
            t3.start();
        }
    }

    000实例原因:三个线程分别都做了num--环节就把执行权让出给下一个线程了。结果三个线程都把前半部分做完才执行System.out.println。导致000

    变量被同时使用测试代码2:

    例如数字10000, 10个线程每个线程循环1000次减去1,最终结果为零。但是并发执行覆盖可能导致未减为0

    /**
     * @ClassName VarNotSafe2
     * @projectName: object1
     * @author: Zhangmingda
     * @description: XXX
     * date: 2021/4/20.
     */
    public class VarNotSafe2 {
        private static int num = 10000;
        private static class MinusNumRannable implements Runnable{
            @Override
            public void run() {
                for(int i=0; i<1000; i++){
                    num--;
                }
                System.out.println(Thread.currentThread().getName() + "计算结果:" + num);
            }
        }
    
        public static void main(String[] args) {
            Runnable runnable = new MinusNumRannable();
            for(int i=0; i<10; i++){
                new Thread(runnable).start();
            }
            try {
                Thread.sleep(3000);
                System.out.println("最终结果:" + num);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    VarNotSafe2

      

    synchronized关键字解决

    /**
     * @ClassName VarNotSafe
     * @projectName: object1
     * @author: Zhangmingda
     * @description: XXX
     * date: 2021/4/20.
     */
    public class VarSafeSynchronized {
        public static int num = 3;
    
        public static class SafeThread implements Runnable {
    
            @Override
            public synchronized void run() {
                num--;
                System.out.println(Thread.currentThread().getName() + "结果==>:" + num);
            }
        }
        public static void main(String[] args) {
            Runnable safeR = new SafeThread();
            Thread t1 = new Thread(safeR,"t1");
            Thread t2 = new Thread(safeR,"t2");
            Thread t3 = new Thread(safeR,"t3");
            t1.start();
            t2.start();
            t3.start();
        }
    }

  • 相关阅读:
    MySQL++:(转)mybatis 常用 jdbcType数据类型
    CF1556F Sports Betting (状压枚举子集DP)
    ICPC Greater New York Region 2020 F
    post方式实现导出/下载文件
    自定义一个v-if
    在vue项目中引用element-ui时 让el-input 获取焦点的方法
    element-select当下拉框数据过多使用懒加载
    vue强制刷新组件更新数据的方式
    .net core efcore dbfirst(sqlserver,mysql,oracle,postgresql)
    camunda安装配置mysql以及整合springboot
  • 原文地址:https://www.cnblogs.com/zhangmingda/p/14680303.html
Copyright © 2011-2022 走看看