您的位置:首页 > 编程语言 > Java开发

《并发编程》--6.Java内存模型(JMM)的关键字volatile

2017-08-18 14:26 561 查看
Java的内存模型(JMM)都是围绕着原子性,有序性,可见性。一些特殊的场合下,需要用volatile等关键字保证这些特性。

当用volatile声明一个变量时,就相当于告诉虚拟机,这个变量极有可能在多个线程中修改。为了确保这个变量被修改后,程序的所有线程都能够意识到这个改动,虚拟机就必须采用一些特殊的手段,保证这个变量的可见性。

声明的代码如下:

static volatile int i = 0;注意:volatile虽然能很大程度的维护原子性,但是不能替代锁
一下一个简单的demo即可说明

public class volatileMain1 {

static volatile int i = 0;
public static class Task implements Runnable {
@Override
public void run(){
for(int k=0;k<10000;k++){
i++;//如果是原子性的,最终的是为100000(10个线程累计加10)
//实际是小于100000的
//证明volatile不能代替锁
}
}
public static void main(String[] args) throws InterruptedException {
Thread[] t = new Thread[10];
for(int i = 0;i<10;i++){
t[i] = new Thread(new Task());
t[i].start();
}
for(int i=0;i<10;i++){
t[i].join();
}
System.out.println(i);
}

}
}


实际的运行结果是小于100000的。。。

另外volatile也能保证数据的可见性和有序性,以后是一个简单的demo

public class volatileMain2 {
private static boolean ready;
private static String name;

private static class ReaderThread extends Thread{
@Override
public void run(){
while(!ready);//虚拟机在client模式下,由于JIT并没有做优化,主线程修改number,ReaderThread发现这个改动,退出程序
//虚拟机在server模式下,由于系统的优化,导致ReaderThread永远无法退出(因为readdy为false)
System.out.println("I am "+name);
}
}

public static void main(String[] args) throws InterruptedException {
new ReaderThread().start();
Thread.sleep(1000);
name = "yemt";
ready = true;
Thread.sleep(10000);
}
}

注意:可以使用Java虚拟机参数-server切换到Server模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息