1. 程式人生 > 其它 >執行緒安全性

執行緒安全性

  • 執行緒安全
當多個執行緒訪問某個類,不管執行時環境採用何種排程方式或者這些執行緒如何交替執行,並且在主調程式碼中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼就稱這個類為執行緒安全的
  • 新建執行緒不安全操作的案例類
public class UnSafeThread {

    private static int num = 0;

    private static CountDownLatch countDownLatch = new CountDownLatch(10);

    /**
     * 每次呼叫對num進行++操作
     */
    public static void  inCreate() {
        num++;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                for (int j = 0; j < 100; j++) {
                    inCreate();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //每個執行緒執行完成之後,呼叫countDownLatch
                countDownLatch.countDown();
            }).start();
        }

        while (true) {
            if (countDownLatch.getCount() == 0) {
                System.out.println(num);
                break;
            }
        }

    }
}
  • 開啟cmd
# 編譯
C:\work\git\spring_learn_repo\concurrent\src\main\java\com\xdclass\synopsis>javac -encoding UTF-8 UnsafeThread.java
# 反編譯
C:\work\git\spring_learn_repo\concurrent\src\main\java\com\xdclass\synopsis>javap -c UnsafeThread.class
Compiled from "UnsafeThread.java"
public class com.xdclass.synopsis.UnSafeThread {
  public com.xdclass.synopsis.UnSafeThread();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void inCreate();
    Code:
       0: getstatic     #2                  // Field num:I
       3: iconst_1
       4: iadd
       5: putstatic     #2                  // Field num:I
       8: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: bipush        10
       5: if_icmpge     29
       8: new           #3                  // class java/lang/Thread
      11: dup
      12: invokedynamic #4,  0              // InvokeDynamic #0:run:()Ljava/lang/Runnable;
      17: invokespecial #5                  // Method java/lang/Thread."<init>":(Ljava/lang/Runnable;)V
      20: invokevirtual #6                  // Method java/lang/Thread.start:()V
      23: iinc          1, 1
      26: goto          2
      29: getstatic     #7                  // Field countDownLatch:Ljava/util/concurrent/CountDownLatch;
      32: invokevirtual #8                  // Method java/util/concurrent/CountDownLatch.getCount:()J
      35: lconst_0
      36: lcmp
      37: ifne          29
      40: getstatic     #9                  // Field java/lang/System.out:Ljava/io/PrintStream;
      43: getstatic     #2                  // Field num:I
      46: invokevirtual #10                 // Method java/io/PrintStream.println:(I)V
      49: goto          52
      52: return

  static {};
    Code:
       0: iconst_0
       1: putstatic     #2                  // Field num:I
       4: new           #18                 // class java/util/concurrent/CountDownLatch
       7: dup
       8: bipush        10
      10: invokespecial #19                 // Method java/util/concurrent/CountDownLatch."<init>":(I)V
      13: putstatic     #7                  // Field countDownLatch:Ljava/util/concurrent/CountDownLatch;
      16: return
}