Synchronized不一定是线程安全的吧?_wait释放同步锁
来源:互联网 发布:苹果4s支持3g网络吗 编辑:程序博客网 时间:2024/05/20 18:44
在做并发开发的时候,为了保证某对象的线程安全,一般都会对其用Synchronized进行保护,比如:
synchronized(obj) {
// Do something with obj.
}
当所有对obj进行的操作,都用同步块保护时,我们一般认为其是线程安全的。
但这个线程安全到底有多安全呢?请先看看这个简单的例子:
代码实现很简单,两个线程同时修改一个对象的属性,在其属性原值基础上进行计算,然后再回写;
但是这里面故意使用了 obj.wait(),实际上造成对synchronized同步锁的释放。
public class synchronizedWrongUse { public static void main(String[] args) throws Exception{ //初始化 SomeoneObject obj = new SomeoneObject(); Worker a = new Worker("A", obj); Worker b = new Worker("B", obj); //启动线程 a.start(); b.start(); //等待线程启动 Thread.sleep(100); //唤醒obj synchronized(obj){ obj.notifyAll(); System.out.println("notifyAll done."); } //等待线程结束 a.join(); b.join(); //输出结果 System.out.println("Amount:"+obj.getAmount());//只有50 } static class Worker extends Thread{ private SomeoneObject obj; public Worker(String name,SomeoneObject obj){ super(name); this.obj = obj; } public void run(){ System.out.println("Worker["+this.getName()+"]started."); synchronized(obj){//为保证obj操作的互斥性,加同步锁,但是wait释放了同步锁 int amount = obj.getAmount(); amount += 50;// try{// obj.wait();//这里wait释放了同步锁// }catch(InterruptedException e){// return;// } obj.setAmount(amount); System.out.println("Worker["+this.getName()+"]setting done."); } } } /** * @author lix *某对象 */ static class SomeoneObject{ int amount;//属性 public int getAmount(){ return amount; } public void setAmount(int amount){ this.amount = amount; } }}
两个线程各 +50,期望结果是100;但实际结果仍然只有50。
接触过事务的人应该能很快理解,在synchronized块中,未必能绝对保证事务一致性;因为wait释放了同步锁。
当然,避免这种情况发生一般来说也很简单:
1、尽量不要将基于原有状态的计算过程被中断,也就是你别在 amount += 50; 中间插入wait;
2、可以做乐观检查,也就是set之前重新检查下当前状态是否与原状态保持一致,不一致就要重新发起计算。
阅读全文
0 0
- Synchronized不一定是线程安全的吧?_wait释放同步锁
- synchronized 线程同步安全
- 线程安全,线程同步,synchronized
- Java synchronized的理解!(线程安全,线程同步)
- 线程安全和线程同步Synchronized
- 线程的同步synchronized
- synchronized线程同步锁
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- Java线程同步:synchronized锁住的是代码还是对象
- IOS开发—JS调用OC(通过非URL的方式)
- 树形dp+树形结构总结
- knockout实现嵌套循环绑定
- python 中列表(list)合并、数组(array)合并
- GotGitHub详细教程
- Synchronized不一定是线程安全的吧?_wait释放同步锁
- iOS开发--一些UITabBarItem属性的设置
- 剑指offer
- 湘潭大学-基于Dragonboard 410c教室资源管理与信息查询系统(二)
- OTA升级相关
- MySQL函数大全及用法示例
- Jquery打造可以上下移动行的表格
- Android源码编译 找不到系统隐藏类(@hide), LOCAL_SDK_VERSION
- 第七周项目5—排队看病模拟