• Java 线程通信之线程安全问题


    什么是线程?

    线程其实就是程序的执行单元,负责自己的运行模块,就比如王者荣耀里面的小兵都是一个个的线程。

    线程安全案例1——单例模式

    懒汉式单例,代码如下:
    在这里插入图片描述
    这是个最基本的懒汉式单例,现在假设开启两个线程t1t2t1线程执行完了第10行代码 ,恰好给t1线程的时间片用完,没有cpu的执行权了,但是还没有来得及执行第11行代码。

    此时同时t2线程也过来执行第10、11行代码,当执行完了第11行代码时,假设刚t2的时间片用完了,释放执行权,t1线程争夺到了执行权,又会开始执行第11代码,又new了一个新对象,分析到这里我们的单例设计模式已经出现问题了。产生了多个对象。

    那么怎么解决多线程带来的安全问题?

    同步锁

    这种由多线程带来的线程安全问题,大家第一时间都会想到用同步锁来解决线程之间对于共享资源的竞争问题,常用的两种锁如下:

    synchronized 锁

    这个锁可以用于同步代码块,方法上,但是要注意是锁的对象是谁。代码改进如下所示:
    在这里插入图片描述
    但是在这个方法上面加锁的话,我们没有办法对其进行性能优化,所以我们可以改成同步代码块的方式,对其进行性能优化,代码如下所示:
    在这里插入图片描述
    改成了同步代码块,我们分析下,t1t2线程过来都要加锁进行判断,t1加锁成功,t2去尝试加锁其实实在做无用功,浪费cpu的资源,那么怎么优化呢?我们可以在外面再加一层判断,代码如下所示:
    在这里插入图片描述
    这样我们就可以提高懒汉式单例的性能。

    lock 锁

    使用Lock锁住第15,16行代码,保证两行代码的原子性即可。
    在这里插入图片描述

    线程安全案例2——卖车票

    这里我们模拟3个窗口(其实是3个线程)一起卖10张车票的场景。

    10张车票代码如下:
    在这里插入图片描述
    我们这里每执行一次就减1,代表每卖出一张票就会少一张票。

    然后模拟窗口代码如下:
    在这里插入图片描述
    卖票的任务就交给多线程去跑,所以这里需要实现Runnable接口,这里我们为了看效果,所以使用while(true)做测试。

    然后开启三个窗口代码如下:
    在这里插入图片描述
    然后给三个线程起一个别名方便看效果。

    运行结果如下所示:
    在这里插入图片描述
    从运行结果分析出,非常不符合现实的问题,就是窗口1卖了0车票,窗口3卖了-1车票,很离谱,不符合现实,不可能出现0、-1这种车票。从这里我们就引发出来线程安全问题。这里可以使用Locksynchronized锁。

    分析一下问题,我们回头看下车票资源,是线程之间共享的资源,代码如下:
    在这里插入图片描述
    我们假设没有加锁之前,我们先假设count=1

    然后t1线程执行完第11行代码,然后暂停,此时是没有执行count--操作的哦,此时count=1
    然后t2线程过来了,也执行完了第11行代码,然后暂停,也没有执行count--,此时count=1
    然后t3过来同样的,也执行完了第11行代码,然后暂停,也没有执行count--,此时count=1

    现在三个线程都已经执行完了这个第11行的判断条件,都进来了,停在了第13行代码

    假设t1醒来,执行完了15行代码,输出结果为1,此时因为执行了count--操作,所以内存中count=0
    然后t2醒来,此时主内存中的count等于0,t2输出结果为 0,同时执行count--操作,则count=-1
    最后t3醒来,此时主内存中的count等于0,执行完了15行代码,t3输出结果为-1,内存中count=-2

    最终分析出问题就是出在了第11行代码和第16行代码没有保证原子性,我们可以将sale()方法加同步锁synchronized,如下所示:
    在这里插入图片描述
    这样就能保证正常卖票了。

    同时我们也可以使用Lock进行加锁代码如下所示:
    在这里插入图片描述

    最终运行结果如下所示:
    在这里插入图片描述

  • 相关阅读:
    市县镇一体化视频会议系统
    刷题笔记26——图论二分图判定
    技术管理进阶——管理者如何做绩效沟通及把控风险
    Spring Boot深度解析:快速开发的秘密
    C语言for循环高手小技巧
    深度学习中的epoch, batch 和 iteration
    Scala函数柯里化(Currying)
    JavaScript-Object.defineProperty函数
    iOS APP上架App Store其中一个步骤就是要把ipa文件上传到App Store
    甲骨文全区登录地址
  • 原文地址:https://blog.csdn.net/qq_35971258/article/details/125615749