91名师指路-头部
91名师指路

java 验证volatile不具有原子性

由于某些原因,现在不支持支付宝支付,如需要购买源码请加博主微信进行购买,微信号:13248254750

volatile的特性:

(1)可见性。

(2)不保证原子性。

(3)禁止指令重排。


代码如下:

package com.mszl.thread;

/**
* 功能:验证volatile 不保证原子性
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
class Acc{

volatile int number=0;

public void addPlus(){
number++;
}

}

public class Volatile1 {

public static void main(String[] args) {
Acc c=new Acc();

for(int i=1; i<=20; i++){ // 创建20个线程
Thread t=new Thread(new Runnable() {
@Override
public void run() {
for(int k=1; k<=1000; k++){ // 每个线程加1000次。一共20个线程。number=20 * 1000
c.addPlus();
}
}
});
t.start();
}

while(Thread.activeCount()>2){ // 因为有gc线程和main线程,所以这里是大于2
Thread.yield(); // 让其他线程先执行
}
System.out.println(Thread.currentThread().getName() + " >>> " + c.number);
}


}


执行结果:

main >>> 19735


注意:这里的执行结果也有可能是20000的,如果遇到了,请多执行几次。


volatile不保证原子性的解决方案:

代码如下:

package com.mszl.thread;

import java.util.concurrent.atomic.AtomicInteger;

/**
* 功能:验证volatile 不保证原子性
* 备注:更多资料请访问 http://www.91mszl.com
* @author bobo teacher
*/
class Acc{

volatile int number=0;

public void addPlus(){
number++;
}

// volatile不保证原子性的解决方案
AtomicInteger ai=new AtomicInteger();
public void addMyAto(){
ai.getAndIncrement(); // 等价于number++
}

}

public class Volatile2 {

public static void main(String[] args) {
Acc c=new Acc();

for(int i=1; i<=20; i++){ // 创建20个线程
Thread t=new Thread(new Runnable() {
@Override
public void run() {
for(int k=1; k<=1000; k++){ // 每个线程加1000次。一共20个线程。number=20 * 1000
c.addPlus();
c.addMyAto();
}
}
});
t.start();
}

while(Thread.activeCount()>2){ // 因为有gc线程和main线程,所以这里是大于2
Thread.yield(); // 让其他线程先执行
}
System.out.println(Thread.currentThread().getName() + " >>> " + c.number);
System.out.println(Thread.currentThread().getName() + " AtomicInteger >>> " + c.ai);
}



}


执行结果:

main >>> 19866
main AtomicInteger >>> 20000


我们涉及到多线程++的时候采用AtomicInteger 来保证原子性。

2019-11-24 12:36:34     阅读(787)

名师出品,必属精品    https://www.91mszl.com

联系博主    
用户登录遮罩层
x

账号登录

91名师指路-底部