[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 args 66 */ 67 public static void main(String[] args) { 68 for (int i = 0; i < numOfThread; i++) { 69 new Thread(new Runnable() { 70 71 @Override 72 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 + 原子变量 方式可以同时保证多线程环境下安全的变量读写。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。