volatile与synchronized的比较

原子性:

操作要么都执行,要么都不执行。
比如:A原有5块石头,B原有3块石头;现有如下操作:
A让C给予B一块石头,那么应该发生的事情有,A失去一块石头,变为4块,B得到一块石头变为5块;此时交易成功。
不排除有意外情况,比如C在给予B的过程中,B出门了,那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,
A还是5块石头,B还是4块石头。
我们把这种要么一起成功(A成功减少一块石头,同时B得到一块石头),要么一起失败(A回到原来状态,B也回到原来状态)的操作叫原子性操作。
如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行。这种特性就叫原子性
i=1+1是原子性操作,i++不是,因为i++实际上分成了3步操作①从内存中读取出变量 i 的值②将 i 的值加1③将 加1 后的值写回内存,这个期间可能其他线程修改了i的值,所以不保证i++的结果=2

可见性:

Java内存的规定:
-线程对共享变量的所有操作都必须在自己的工作内存中进行,不可直接从主内存中读写; -不同线程之间无法直接访问其他线程工作内存中的变量,线程间的变量值的传递需要通过主内存,子线程中的都是主线程变量的副本。如果不加volatile或synchronized,那么子线程中对副本的操作结果将不能刷到主内存中

volatile 与 synchronized 的比较

volatile主要用在多个线程感知实例变量被更改了的场合,从而使得各个线程获得最新的值。它强制线程每次从主内存中讲到变量,而不是从线程的私有内存中读取变量,从而保证了数据的可见性。
关于synchronized,可参考:JAVA多线程之Synchronized关键字–对象锁的特点
比较:
①volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法
②volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。
synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。

线程安全性

线程安全性包括两个方面,①可见性。②原子性。
从上面自增的例子中可以看出:仅仅使用volatile并不能保证线程安全性。而synchronized则可实现线程的安全性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值