java volatile关键字使用方法及注意事项
javavolatile关键字使用方法及注意事项
什么是volatile关键字
volatile关键字在多线程程序中起着很重要的作用。当多个线程操作同一个变量时,每个线程将拥有对那个变量的本地缓存拷贝,因此,当某一个线程修改了这个变量的值时,实际上修改的是它本地缓存中的变量值,而不是主内存中的变量值,操作这个变量的其他线程并不知道这个变量的值被改变了。为了避免这种情况,我们可以用valatile关键字声明这个变量,用valatile声明了这个变量之后,变量将不在本地缓存中保存,而在主内存中保存,当有线程修改了它的值以后,它的更新值将被更新到主内存当中,随后,其他线程也能访问更新后的值。当一个变量被声明为volatile后,java内存模型确保所有使用该变量的线程能看到相同的、一致的值。
volatile关键字使用
首先,创建VolatileData类,代码如下:
publicclassVolatileData{
//声明为volatile类型
privatevolatileintcounter=0;
/**
*返回counter变量的值
*@return
*/
publicintgetCounter(){
returncounter;
}
/**
*自增counter变量的值
*/
publicvoidincreaseCounter(){
++counter;
}
}
接下来创建VolatileThread类,代码如下:
publicclassVolatileThreadextendsThread{
privatefinalVolatileDatavolatileData;
publicVolatileThread(VolatileDatavolatileData){
this.volatileData=volatileData;
}
/**
*调用VolatileData类中的两个方法,进行取值和自增操作
*/
@Override
publicvoidrun(){
intoldValue=volatileData.getCounter();
System.out.println("[Thread"+Thread.currentThread().getId()+"]:Oldvalue="+oldValue);
volatileData.increaseCounter();
intnewValue=volatileData.getCounter();
System.out.println("[Thread"+Thread.currentThread().getId()+"]:Newvalue="+newValue);
}
}
最后,创建VolatileMain类,对以上程序进行测试,代码如下:
publicclassVolatileMain{
privatefinalstaticintTOTAL_THREADS=2;
publicstaticvoidmain(String[]args)throwsInterruptedException{
VolatileDatavolatileData=newVolatileData();
Thread[]threads=newThread[TOTAL_THREADS];
for(inti=0;i
在VolatileMain类中,使用了两个线程来访问volatile变量,输出如下:
[Thread10]:Oldvalue=0
[Thread11]:Oldvalue=0
[Thread10]:Newvalue=1
[Thread11]:Newvalue=2
从输出可以看到,首先,两个线程都输出了相同的值,接着,在increaseCounter方法被调用之后,两个线程都访问和输出了最新的volatile变量的值。
happens-before关系
在使用volatile关键字时,不得不提一下java内存模型的happens-before关系。happens-before关系是java内存模型的一个重要方面。它建立在两个不同的事件之间,使第一个事件对对象的所有改变都可以被第二个事件看到和反映出。比如当一个线程对volatile变量进行写操作后,另一个线程随后访问该变量,happens-before关系就建立了。因此,所有对volatile变量的改变对其他线程来说是可见的。
需要注意的
当在程序中使用volatile关键字时,我们必须注意以下几点:
- volatile关键字并不能消除原子之间的同步操作的需要,因为内存一致性错误仍然是可能的
- 使用原子变量比使用synchronized同步代码更有效率,但是为了避免内存一致性错误,需要作出额外的努力
- volatile关键字不能替代synchronized同步代码块和方法
以上就是关于javavolatile关键字的使用方法,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!