您的位置:首页 > 其它

Volatile关键字的使用

2017-04-12 17:20 232 查看
在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。

它在某些情况下比synchronized的开销更小,本文将深入分析在硬件层面上Inter处理器是如何实现Volatile的,通过深入分析能帮助我们正确的使用Volatile变量。


Volatile的官方定义

Java语言规范第三版中对volatile的定义如下: java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致的更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明成volatile,java线程内存模型确保所有线程看到这个变量的值是一致的。


为什么要使用Volatile

Volatile变量修饰符如果使用恰当的话,它比synchronized的使用和执行成本会更低,因为它不会引起线程上下文的切换和调度。

看下面代码,如果不使用Volatile,则其他两个线程则无法得到state。

该程序是3个线程,按顺序打印。

启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到75. 程序的输出结果应该为:

 

线程1: 1

线程1: 2

线程1: 3

线程1: 4

线程1: 5

 

线程2: 6

线程2: 7

线程2: 8

线程2: 9

线程2: 10

...

 

线程3: 71

线程3: 72

线程3: 73

线程3: 74

线程3: 75

public class PrintNum extends Thread {
static int c = 0;
static volatile int state = 0;
private int id;

@Override
public synchronized void run() {
while (state < 15) {
if (state % 3 == id) {
for (int j = 0; j < 5; j++) {
c++;
System.out.format("Thread %d: %d %n", id, c);
}
state++;
}
}
}

public PrintNum(int id) {
this.id = id;
}

public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new PrintNum(i).start();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: