volatile关键字能保证原子性吗?
TestVolatileAtomicity
public class TestVolatileAtomicity extends Thread {
volatile public static int count;
private static void addCount() {
for (int i = 0; i < 100; i++) {
count = i;
}
System.out.println(“count=” + count);
}
@Override
public void run() {
addCount();
}
public static void main(String[] args) {
TestVolatileAtomicity[] testVolatileAtomicities = new TestVolatileAtomicity[100];
for (int i = 0; i < 100; i++) {
testVolatileAtomicities[i] = new TestVolatileAtomicity();
}
for (int i = 0; i < 100; i++) {
testVolatileAtomicities[i].start();
}
}
}
运行结果:
count=99
count=99
count=2
count=99
count=99
count=55
count=97
count=99
count=99
上面的“count=i;”是一个原子操作,但是运行结果大部分都是正确结果99,但是也有部分不是99的结果。
解决办法: 使用synchronized关键字加锁(Lock和AtomicInteger原子类也可以)
修改TestVolatileAtomicity.java如下:
这样运行输出的count就都为99了,所以要保证数据的原子性还是要使用synchronized关键字。 ### 四 synchronized关键字和volatile关键字比较
- volatile关键字是线程同步的轻量级实现,volatile性能肯定比synchronized关键字要好。
- volatile关键字只能用于变量,synchronized关键字可以修饰方法以及代码块。synchronized关键字在6之后,为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用synchronized关键字更多一些。
- 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。
- volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者皆可保证。
volatile关键字用于解决变量在多个线程之间的可见性,而synchronized关键字解决的是多个线程之间
上一篇: 继承的几种方式及优缺点_前端培训
下一篇: 常规性能调优并行度调节_大数据培训