Java Thread系列(六)volatile
volatile 关键字具备可见性,不具备原子性。主要作用是使变量在多个线程间可见。但不具备原子性(同步性),可以算一个轻量级的 synchronized ,性能要比 synchronized 强很多,不会造成阻塞。
一、volatile 可见性
public class VolatileThread extends Thread {
//volatile修辞的变量,变量发生变化时会强制性从主线程栈中读取该变量
private volatile boolean isRuning = true;
public void setIsRuning(boolean isRuning) {
this.isRuning = isRuning;
System.out.println("变量isRuning设置成功");
}
public void run () {
//主线程调制的变量isRuning生效,程序退出while语句
while (isRuning) {
// do ...
}
}
public static void main(String[] args) throws InterruptedException {
VolatileThread vt = new VolatileThread();
vt.start();
Thread.sleep(1000);
//主线程调制的变量isRuning在线程vt中生效,即实现了可见性
vt.setIsRuning(false);
}
}
二、volatile 非原子性
要想保证原子性,可以用 synchronized 修辞,或使用 AtomicInteger 类
import java.util.concurrent.atomic.AtomicInteger;
public class VolatileNotAtomic extends Thread {
private static volatile int count;
//private static AtomicInteger count = new AtomicInteger(0);
public static void addCount() {
for (int i = 0; i < 1000; i++) {
count++;
//count.incrementAndGet();
}
System.out.println(count);
//使用volatile关键字,最后的结果不是1000*10
//要想保证原子性,可以使用AtomicInteger类,只保证最后的结果正确,中间可能有误
}
public void run () {
addCount();
}
public static void main(String[] args) throws InterruptedException {
VolatileNotAtomic[] vna = new VolatileNotAtomic[10];
for (int i = 0; i < 10; i++) {
vna[i] = new VolatileNotAtomic();
}
for (int i = 0; i < vna.length ; i++) {
vna[i].start();
}
}
}
参考:
-
《Java并发编程:volatile关键字解析》:http://www.importnew.com/18126.html
-
《volatile的适用场景》:https://blog.csdn.net/vking_wang/article/details/9982709
-
《正确使用 Volatile 变量》:https://www.ibm.com/developerworks/cn/java/j-jtp06197.html
每天用心记录一点点。内容也许不重要,但习惯很重要!