java 线程安全问题
如果要多线程并发修改一个数据结构,例如我们之前写的队列,如果一个线程对其执行读取数据,而另一个线程对其取出数据,这样就会引发线程安全问题。实际上对于上述线程安全,不过是数据结构为空情况下抛出的异常。最简单的线程安全了
关于线程安全问题
数据同步
一张图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ac0fRfZH-1651656425649)(C:\Users\moutainman\AppData\Roaming\Typora\typora-user-images\image-20220504135348785.png)]
当A对数据进行修改但还没有完全提交,此时B又来对数据进行操作,这样就会造成数据不同步。
指令
更有甚者,由于一条java语句包含多个指令,当一条语句的部分指令并未执行完成,此时另一个线程抢占了执行权,并完成所有指令。此时先前的线程再将指令完成,这样一来,他会抹去第二个线程所作的数据更新。
accounts[用户A] += money;
这条语句,可能如下分解为如下指令:
1. accounts[用户A]加载到寄存器
2. +money
3. 将结果返回 accounts[用户A]
怎么抹去线程所作的数据更新,这就容易理解了吧
线程逻辑问题
拿刚才的用户转账问题来说,系统实现用户转账,如果超额了怎么办,一个人账户的余额为负数,却还能不停的转账。岂有此理!
所以当一个转钱的金额大于用户所剩余额,应该让其进行进入线程等待集。带其他线程完整执行任务后,再将其从等待线程拉出。
死锁
如上讲述,当所有线程都进入等待集,这也是一种死锁现象。很遗憾java并没有提供工具类打破死锁现象,应该在程序设计时尽可能确保死锁。
死锁现象。很遗憾java并没有提供工具类打破死锁现象,应该在程序设计时尽可能确保死锁。