线程安全

线程安全

多线程的n++和n–之后

public class ThreadDemo {
    private static class Counter{
        private long n=0;
        public void increment(){
            n++;
        }
        public void decrement(){
            n--;
        }
        public long value(){
            return n;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        final int COUNT=1000_0000;
        Counter counter=new Counter();
        Thread thread=new Thread(()->{
            for (int i = 0; i < COUNT ; i++) {
                counter.increment();
            }
        },"小代");
        thread.start();
        for (int i = 0; i <COUNT ; i++) {
            counter.decrement();
        }
        thread.join();
        //期望最终结果应该是0
        System.out.println(counter.value());
    }
}

线程安全的概念:
如果多线程环境下运行的结果是符合预期的,就是在单线程环境下运行的结果,则说明这个线程是安全的。
线程不安全的原因:
1.原子性
我们把一段代码想象成一个房间,每个线程就是要进入这个房间的人。如果没有任何机制保证,A进入房间之后,还
没有出来;B 是不是也可以进入房间,打断 A 在房间里的隐私。这个就是不具备原子性的。
那我们应该如何解决这个问题呢?是不是只要给房间加一把锁,A 进去就把门锁上,其他人是不是就进不来了。这样
就保证了这段代码的原子性了。
有时也把这个现象叫做同步互斥,表示操作是互相排斥的。
2、可见性:
先了解内存
在这里插入图片描述
为了提高效率,JVM在执行过程中,会尽可能的将数据在工作内存中执行,但这样会造成一个问题,共享变量在多线
程之间不能及时看到改变
,这个就是可见性问题。

3、代码的顺序性
什么是代码重排序
一段代码是这样的:

  1. 去前台取下 U 盘
  2. 去教室写 10 分钟作业
  3. 去前台取下快递
    如果是在单线程情况下,JVM、CPU指令集会对其进行优化,比如,按 1->3->2的方式执行,也是没问题,可以少跑
    一次前台。这种叫做指令重排序。
public class ThreadDemo2 {
    private static class Counter{
        private int n1=0;
        private int n2=0;
        private int n3=0;
        private int n4=0;
        private int n5=0;
        private int n6=0;
        private int n7=0;
        private int n8=0;
        private int n9=0;
        private int n10=0;
        public void write(){
            n1=1;
            n2=2;
            n3=3;
            n4=4;
            n5=5;
            n1=6;
            n2=7;
            n3=8;
            n4=9;
            n5=10;
        }
        public void read(){
            System.out.println("n1="+n1);
            System.out.println("n2="+n2);
            System.out.println("n3="+n3);
            System.out.println("n4="+n4);
            System.out.println("n5="+n5);
            System.out.println("n6="+n6);
            System.out.println("n7="+n7);
            System.out.println("n8="+n8);
            System.out.println("n9="+n9);
            System.out.println("n10="+n10);
        }
    }

    public static void main(String[] args) {
        Counter counter=new Counter();
        Thread thread1=new Thread(()->{
            counter.read();
        },"读");
        Thread thread2=new Thread(()->{
            counter.write();
        },"写");
        thread1.start();
        thread2.start();
    }
}
/*
执行结果:
n1=6
n2=7
n3=8
n4=9
n5=10
n6=0
n7=0
n8=0
n9=0
n10=0
 */

代码重排序会给多线程带来什么问题
刚才那个例子中,单线程情况是没问题的,优化是正确的,但在多线程场景下就有问题了,什么问题呢。可能快递是
在你写作业的10分钟内被另一个线程放过来的,或者被人变过了,如果指令重排序了,代码就会是错误的。

解决线程不安全的问题

//解决线程不安全的问题,给每个方法之前都加上synchronized 关键字,程序运行结果就会正确

public class ThreadDemo3 {
    private static class Counter{
        private long n=0;
        public synchronized void increment(){
            n++;
        }
        public synchronized void decrement(){
            n--;
        }
        public synchronized long value(){
            return n;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        final int COUNT=1000_0000;
       Counter counter=new Counter();

        Thread thread=new Thread(()->{
            for (int i = 0; i < COUNT ; i++) {
                counter.increment();
            }
        },"代");
        thread.start();
        for (int i = 0; i <COUNT ; i++) {
            counter.decrement();
        }
        thread.join();
        //期望最终结果应该是0
        System.out.println(counter.value());
    }
}
/*
执行结果:0
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值