首页 > 代码库 > [Java多线程] volatile 关键字正确使用方法

[Java多线程] volatile 关键字正确使用方法

    volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性,即多线程环境中,使用 volatile 关键字的变量仅可以保证不同线程读取变量时,可以读到最新修改的变量值,但是修改变量值时,却不能保证线程安全(可能存在写值覆盖现象)。以下测试代码,展示了使用volatile关键字的几种方式。

 

 1 /** 2  * <b>volatile 关键字正确用法</b><br> 3  * @author        Gaylen 4  * @version        V1.1.0 5  * history 6  * 1.1.0, 2014年11月20日        Gaylen            FE 7  * @since        Java 6.0 8  */ 9 public class TestVolatile {10 11     /** volatile + atomic 保证读写安全 */12     public static volatile AtomicInteger count1 = new AtomicInteger(0);13 14     /** volatile 实现读安全,但不能保证写安全 */15     public static volatile int count2 = 0;16 17     /** volatile + synchronized 实现读写安全 */18     public static volatile int count3 = 0;19 20     /** static 仅保证全局唯一,但不能保证读写安全 */21     public static int count4 = 0;22 23     public static synchronized void count3Increment() {24         TestVolatile.count3++;25     }26 27     /** 测试线程数 */28     public static final int numOfThread = 1000;29 30     /** 线程辅助类,保证所有线程执行完毕 */31     private static CountDownLatch countDownLatch = new CountDownLatch(numOfThread);32 33     public static void increment() {34         try {35             Thread.sleep(1);36         } catch (InterruptedException e) {37         }38         count1.getAndIncrement();39         count2++;40         count3Increment();41         count4++;42     }43 44     /**45      * 输出结果46      * 等待所有线程执行完毕后,输出结果47      */48     public static void print() {49         try {50             countDownLatch.await();51         } catch (InterruptedException e) {52             e.printStackTrace();53         }54         System.out.println("运行结果: count1=" + TestVolatile.count1.get());55         System.out.println("运行结果: count2=" + TestVolatile.count2);56         System.out.println("运行结果: count3=" + TestVolatile.count3);57         System.out.println("运行结果: count4=" + TestVolatile.count4);58         System.out.println("---------------------------------------");59 60     }61 62     /**63      * <b>程序入口</b><br>64      * 同时启动1000个线程,进行增加操作65      * @param args66      */67     public static void main(String[] args) {68         for (int i = 0; i < numOfThread; i++) {69             new Thread(new Runnable() {70 71                 @Override72                 public void run() {73                     for (int index = 0; index < 1000; index++) {74                         TestVolatile.increment();75                     }76                     countDownLatch.countDown();77                 }78             }).start();79         }80         print();81     }82 }

测试程序输出结果如下:

运行结果: count1=1000000
运行结果: count2=998528
运行结果: count3=1000000
运行结果: count4=999892
---------------------------------------

通过测试程序可知,使用 volatile + synchronized 方式 或者 volatile + 原子变量 方式可以同时保证多线程环境下安全的变量读写。

 

[Java多线程] volatile 关键字正确使用方法