上一篇:教你在停车前为线程配个“保镖” | 带你学《Java语言高级特性》之十三
【本节目标】
通过阅读本节内容,你应当掌握volatile关键字的适用范围及其作用,认识到volatile关键字虽然使数据操作直接面向原始变量,使得变量完成一定意义上的同步,但仍无法替代synchronized的作用。
volatile关键字
在多线程定义中,volatile关键字主要是在属性上使用的,表示此属性为直接数据操作,而不进行副本的拷贝处理。这样的话在一些书上就将其错误的理解为同步属性了。
图一 volatile
范例:卖票程序
class MyThread implements Runnable {
private volatile int ticket = 5 ; //直接内存操作
@Override
public void run() {
synchronized (this){
while (this.ticket > 0) {
try {
Thread.sleep(100) ;
} catch (InterruptedException e) {
e.printStackTrace() ;
}
System.out.println(Thread.currentThread().getName() + "卖票处理,ticket = " + this.ticket--) ;
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread() ;
new Thread(mt, "票贩子A").start() ;
new Thread(mt, "票贩子B").start() ;
new Thread(mt, "票贩子C").start() ;
}
}
图二 解释volatile关键字
在正常进行变量处理的时候往往会经历如下的几个步骤:
- 获取变量原有的数据内容副本;
- 利用副本为变量进行数学计算;
- 将计算后的变量,保存到原始空间之中;
而如果一个属性上追加了volatile关键字,表示的就是不使用副本,而是直接操作原始变量,相当于节约了拷贝副本、重新保存的步骤。
面试题:请解释volatile与synchronized的区别
1)volatile主要在属性上使用,而synchronized是在代码块与方法上使用;
2)volatile无法描述同步的处理,它只是一种直接内存的处理,避免了副本的操作,而synchronized是实现同步的。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学