volatile关键字

并发编程中有三个问题:原子性,可见性和有序性。

原子性:即一个操作或者多个操作要么全部执行且执行过程中不会被打断,要么就都不执行。

可见性:指多个线程访问同一变量时,一个线程修改了变量值,其他线程能够立即看到修改的值。

有序性:有序性指程序执行的顺序按照代码的先后顺序执行。

volatile不能保证原子性

如下代码示例:

    public volatile int num = 0;
   public void increase(){
       num++;
   }
   public static void main(String[] args) throws InterruptedException {
       VolatileTest volatileTest = new VolatileTest();
       for (int i=0; i<10; i++){
           new Thread(){
               @Override
               public void run(){
                   for (int j=0; j<1000; j++){
                       volatileTest.increase();
                   }
               }
           }.start();
       }
       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println(volatileTest.num);
   }
}

使用volatile必须具备以下2个条件:

1.对变量的写操作不依赖于当前值.

2.该变量没有包含在具有其他变量的不变式中.

volatile使用场景

运行结果发现每次都不一样,我们期望的值是:10000,导致原因如下:

自增操作不是原子性的,而且volatile也无法保证对变量操作的原子性

如想保证原子性操作可以使用如下方法:

1.increase方法前加synchronized关键字。

2.increase方法中加锁。

3.使用AtomicInteger类。

原文地址:https://www.cnblogs.com/lucky-girl/p/9817566.html