volatile关键字

来源:互联网 发布:mac ftp 看不到文件夹 编辑:程序博客网 时间:2024/06/05 16:21

1.一旦共享变量被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的;
2)禁止进行指令重排序。

2.所谓volatile的措施,就是
1)每次从内存中取值,不从缓存中拿值。这就保证了用volatile修饰的共享变量,每次的更新对其他线程立即。既然保证了其他线程的立即可见,也就无法保证原子性。
2)由于有些时候对volatile的操作,不会被保存,说明不会造成阻塞。不可用与多线程环境下的计数器。

/** * 功能:发起50个线程,每个线程对race变量进行10000次自增操作,如果代码能够正确并发,则最终race的结果应为500000,但是实际的运行结果却小于20000. * @author NST_Xx * */public class VolatileTest {    public static volatile int race = 0;    public static void increase(){        race++;    }    private static final int THREADS_COUNT = 50;    public static void main(String[] args) {        Thread[] threads = new Thread[THREADS_COUNT];        for(int i=0;i<THREADS_COUNT;i++){            threads[i] =new Thread(new Runnable(){                @Override                public void run() {                    for(int i = 0;i<10000;i++){                        increase();                    }                }});            threads[i].start();        }        while(Thread.activeCount()>1)            Thread.yield();        System.out.println(race);    }}

运行结果
460311<500000,这是由于race++操作不是原子操作,导致一些线程对race变量的修改丢失。
注:参考牛客网讨论

0 0
原创粉丝点击