Java:Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好
文章图片
文章图片
文章图片
文章图片
文章图片
文章图片
【Java:Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好】
文章图片
Java 线程不安全分析
线程不安全
线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下:
模拟网络延迟演示线程不安全
在线程中的run方法上不能使用throws来声明抛出异常 , 所以在run方法中调用有可能出现异常的代码时 , 只能使用try-catch将其捕获来处理 。
原因是:子类覆盖父类方法时不能抛出新的异常 , 父类的run方法都没有抛出异常 , 子类就更加不能抛出异常了 。 详情可查看我的另一篇文章 :Java基础之异常处理机制
在上述案例中 , 通过引入Thread.sleep();来模拟网络延迟 , 该方法的作用是让当前线程进入睡眠状态10毫秒 , 此时其他线程就可以去抢占资源了 , 方法的参数是睡眠时间 , 以毫秒为单位 。
通过观察运行结果 , 发现了问题:
小红、小强两个小朋友都抢到了14号气球
在运行结果中 , 小红、小强两个小朋友都抢到了14号气球 , 也就是14号气球被抢到了2次 。 我们来梳理线程的运行过程来看看发生了什么:
- 小强和小红两个线程都拿到了14号气球 , 由于线程调度 , 小强获得了CPU时间片 , 打印出了抢到的气球 , 而小红则进入睡眠;小强在打印后对num做了减一操作 , 此时num为13;
- 小明线程开始运行 , 抢到了13号气球 , 并对num做了减一操作 , 此时num为12;
- 小红线程醒来 , 打印出抢到的14号气球;此时的num为12 , 减一后结果为11;
- 由于多个线程是并发操作 , 所以对num做判断时可能上一个线程还未对num减一 , 所以都能通过(num > 0)的判断;
运行结果中出现了本不该出现的0 和 -1
运行结果中出现了本不该出现的0和-1 , 因为按照正常逻辑 , 气球数量到1之后就不应该被打印和减一了 。 出现这样的结果是因为出现了以下的执行步骤:
推荐阅读
- 程序员■Java程序员必知:HashMap进行put操作会不会引起死循
- 课工场郑州翔天信鸽|JavaScript最常用,java是主流,JetBrains公布编程语言排名
- 猿灯塔|POI Excel,Java架构-Apache
- 【Java】github上标星70.5k,贼火的Java突击手册,全面详细对标阿里P7
- 「编程」后台编程语言互相争执,为何前端公认JavaScript?
- 腾讯@JAVA如何连接数据库
- Java■Java仍然排名第一,但Kotlin不容小视了
- 「javascript」为什么NodeJS是创业公司的首选?了解用于Web开发的NodeJS
- 人世繁华|进行面向对象程序设计深剖,可以一学,大牛带你深入Java核心技术
- 罗超|汽车越智能越不安全?,亏电溜车、刹车失灵