2016-11-12 79 views
0

我必須證明(使用代碼)類(在.jar文件中)不是線程安全的。證明這個類是線程安全的嗎?

我明白問題在問什麼,我只是不確定如何處理這個問題的編碼部分。

+1

爲什麼不循環,不斷的值設置爲同樣的事情,並檢查它是相同的,而你有另一個線程一遍又一遍遞減。如果一次失敗,它不是線程安全的。 – Araymer

+0

您需要檢查該類所做的工作,確定它不是線程安全的,並編寫一個利用它的測試。沒有可以執行的通用測試,它會執行此操作。 –

回答

4

證明該類不是線程安全的可能只是一些代碼,它演示了它可以使該類以非線程安全的方式運行。 (通過存在證明)

例如,這可能是一個程序具有兩個線程:

  • 一個線程設置到計數器N和睡覺。
  • 第二個線程將計數器遞減N次
  • 第一個線程喚醒並測試計數器是否耗盡。

重複這幾句(百,千,萬)次

如果有一個線程安全問題,那麼depleted測試可能會給出錯誤的答案。

但要注意,對於這樣的線程安全問題黑盒測試是有點碰運氣:

  • 測試的實際行爲承擔責任是根據不同的硬件平臺等上改變

  • 如果被測試的代碼被視爲黑盒子,您無法確切知道它可能可能具有哪些線程安全問題,或者如何(完全)觸發它們。

  • 當設計這樣的測試時,很容易做一些某種類似的事情serendipitous同步......這可以防止線程安全問題顯示自身。

事實上,你不能清楚地顯示線程安全問題並不意味着他們不在那裏。您無法通過測試來證明代碼是線程安全的。


最後,API設計顯然不是可重入的。由於方法是static,因此只有一個計數器,並且它一次只能用於一件事。但是,這不是一個線程安全問題。我會稱這是一個API設計/可用性問題,而不是線程安全問題。

1 - ...除非執行真的很奇怪;例如是使用線程本地狀態。但是,這應該在API規範中記錄。

2 - 如果設置考題的人在接受併發術語方面並不是真正的速度,那麼他們可能會不同意我的觀點。

0

由於斯蒂芬ç已經給予了全面的答案,我想爲他的建議和您所提供的方法提供了Java示例:

public class Tester { 

    private static int value; 

    public static void main(String[] args) { 

     Runnable decrementRunnable = new Runnable() { 
      @Override 
      public void run() { 

       while (!depleted()) { 
        decrement(); 
       } 

      } 
     }; 

     set(10); 

     Thread decrementThread = new Thread(decrementRunnable); 
     decrementThread.start(); 

     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     if (depleted()) { 
      System.out.println("Not thread-safe."); 
     } 

    } 

    private static void set(int i) { 
     value = i; 
    } 

    private static boolean depleted() { 
     return value <= 0; 
    } 

    private static void decrement() { 
     value--; 
    } 

}