一个普通的Java类:
package org.ccnt.concurrence; public class VolatileTest { public static volatile int race = 0; public static void increate() { race ++; } private static final int THREAD_COUNT = 20; public static void main(String[] args) { Thread[] threads = new Thread[THREAD_COUNT]; for (int i=0; i<THREAD_COUNT; i++) { threads[i] = new Thread(new Runnable() { @Override public void run() { for (int i=0; i<10000; i++){ increate(); } } }); threads[i].start(); } while (Thread.activeCount() > 1) { Thread.yield(); } System.out.println(race); } }
现在我们使用JDK带的反编译工具javap来反编译VilatileTest.class,先执行下面的命令:
javap org.ccnt.concurrence.VolatileTest > VolatileTest.jad
VolatieTest.jad
Compiled from "VolatileTest.java" public class org.ccnt.concurrence.VolatileTest { public static volatile int race; static {}; public org.ccnt.concurrence.VolatileTest(); public static void increate(); public static void main(java.lang.String[]); }
查看字节码:
javap -c org.ccnt.concurrence.VolatileTest > VolatileTest.txt
VolatileTest.txt
Compiled from "VolatileTest.java" public class org.ccnt.concurrence.VolatileTest { public static volatile int race; static {}; Code: 0: iconst_0 1: putstatic #13 // Field race:I 4: return public org.ccnt.concurrence.VolatileTest(); Code: 0: aload_0 1: invokespecial #18 // Method java/lang/Object."<init>":()V 4: return public static void increate(); Code: 0: getstatic #13 // Field race:I 3: iconst_1 4: iadd 5: putstatic #13 // Field race:I 8: return public static void main(java.lang.String[]); Code: 0: bipush 20 2: anewarray #25 // class java/lang/Thread 5: astore_1 6: iconst_0 7: istore_2 8: goto 37 11: aload_1 12: iload_2 13: new #25 // class java/lang/Thread 16: dup 17: new #27 // class org/ccnt/concurrence/VolatileTest$1 20: dup 21: invokespecial #29 // Method org/ccnt/concurrence/VolatileTest$1."<init>":()V 24: invokespecial #30 // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V 27: aastore 28: aload_1 29: iload_2 30: aaload 31: invokevirtual #33 // Method java/lang/Thread.start:()V 34: iinc 2, 1 37: iload_2 38: bipush 20 40: if_icmplt 11 43: goto 49 46: invokestatic #36 // Method java/lang/Thread.yield:()V 49: invokestatic #39 // Method java/lang/Thread.activeCount:()I 52: iconst_1 53: if_icmpgt 46 56: getstatic #43 // Field java/lang/System.out:Ljava/io/PrintStream; 59: getstatic #13 // Field race:I 62: invokevirtual #49 // Method java/io/PrintStream.println:(I)V 65: return }