volatile与synchronized

数据库事务的特性

1.原子性

原子性指的是一个操作不可中断,要么全部执行成功要么全部执行失败。即多个线程一起执行时,一个操作一旦开始,就不会被其他线程干扰。
由原子性变量操作read,load,use,assign,store,write,可以大致认为基本数据类型的访问读写具备原子性(例外就是long和double的非原子性协定)。

2.可见性

可见性是指当一个线程修改了共享变量后,其他线程能够立即得知这个修改。

3.有序性

在java内存模型中说过,为了性能优化,编译器和处理器会进行指令重排序;也就是说java程序天然的有序性可以总结为:如果在本线程内观察,所有的操作都是有序的;如果在一个线程观察另一个线程,所有的操作都是无序的。在单例模式的实现上有一种双重检验锁定的方式(Double-checked Locking)。代码如下:
volatile与synchronized

volatile与synchronized的差别

volatile只能修饰实例变量和类变量,而synchronized可以修饰方法,以及代码块。

volatile保证数据的可见性但不保证原子性(多线程进行写操作,不保证线程安全);而synchronized是一种排他(互斥)的机制。volatile用于禁止指令重排序:可以解决单例双重检查对象初始化代码执行乱序问题。

volatile可以看做是轻量版的synchronized,volatile不保证原子性,但是如果是对一个共享变量进行多个线程的赋值,而没有其他的操作,那么就可以用volatile来代替synchronized,因为赋值本身是具有原子性的,而volatile又保证了可见性,所以就可以保证线程安全了。

总结

1.volatile修饰符适用于以下场景:某个属性bb被多个线程共享,其中有一个线程修改了此属性,并且其他线程可以立即得到修改后的值;或者作为触发器,实现轻量级同步。

2.volatile属性的读写操作都是无锁的,他不能替带synchronized,因为他没有提供原子性和互斥性。因为无锁,不需要花费时间在获取锁和释放锁上,所以说它是低成本的。

3.volatile只能作用于属性,我们用volatile修饰属性,这样compilers就不会对这个属性做指令重排序。

4.volatile提供了happens-before保证,对volatile变量v的写入happens-befores所有其他线程后续对v的读操作。

5.volatile提供了可见性,任何一个线程对其的修改将立马对其他线程可见,volatiless属性不会被线程缓存,始终从主存中获取。

6.volatile可以使long和double的赋值是原子性的。

7.volatile也可以在单例双重检查中实现可见性和禁止指令重排序,从而保证安全性。

相关文章: