volatile的使用原则

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/4352802.html

 

volatile关键字

对于普通变量,在一个线程中更新变量值,则在其他线程中该变量的值并不会改变(存在时间差)。如果需要在其他线程中立即可见,需要使用 volatile 关键字。volatile 不能代替锁,一般认为volatile 比锁性能好(不绝对)。

 

例:两条线程,使用一个标志用于控制一条线程的循环,该标志由另一条线程进行操作。即一条读,一条写。若该标志没有被volatile修饰,则线程中循环永远无法结束。

public class TestMain {

    static volatile boolean flag = true;
    
    public static void main(String[] args) throws InterruptedException {
        
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (flag) {}
                System.out.println(Thread.currentThread().getName() + "线程停止,死循环被打开");
            }
        }).start();
        
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                flag = false;
                System.out.println(Thread.currentThread().getName() + "修改flag为" + flag);
            }
        }).start();

        Thread.sleep(Integer.MAX_VALUE);
    }
}

 

例:(书上的例子)通过一个程序理解volatile。使用-server 的JVM 运行该程序,若没有使用volatile则程序中while永远无法停止。VolatileStopThread只会在自身线程内存中查看stop的值,永远不会更新。

public class VolatileStopThread extends Thread {

    private volatile boolean stop = false;

    public void stopMe() {
        stop = true;
        System.out.println("stop = " + stop);
    }

    public void run() {
        int i = 0;
        while (!stop) {
            i++;
        }
        System.out.println("Stop thread");
    }

    public static void main(String args[]) throws InterruptedException {
        VolatileStopThread t = new VolatileStopThread();
        t.start();
        Thread.sleep(1000);
        t.stopMe();
        Thread.sleep(1000);
    }

}

 

 

 

volatile的使用原则

理解volatile关键字是熟悉Java并发编程的必经之路。如果要彻底理解volatile,首先需要理解Java内存模型。

volatile是java提供的一个轻量级的同步机制,用来对被修饰的变量进行同步。

使用volatile修饰的变量会对多个线程可见,也就是说任何线程都可以看到被volatile修饰的变量的最终值。

volatile并不能替代synchronized,因为volatile只提供了可见性,并没有提供互斥性;在多线程并发修改某个变量值时,依然会出现并发问题。

所以volatile最适合用的场景是一个线程修改被volatile修饰的变量,其他多个线程获取这个变量的值。

当多个线程并发修改某个变量值时,必须使用synchronized来进行互斥同步。

 

 

关于volatile的性能

若一个变量用volatile修饰,那么对该变量的每次读写,CPU都需要从主内存读取,性能肯定受到一定影响。

也就是说:volatile变量远离了CPU Cache,所以没那么高效。

 

 

 

 

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/4352802.html

 

posted @ 2015-03-20 09:11  LaplaceDemon  阅读(2273)  评论(0编辑  收藏  举报