2017-04-24 38 views
-1

此問題來自共享java資源的部分。通過使任務取決於非任務對象來避免競爭條件

請注意,在此示例中,可以取消的類不是可運行的。相反,所有依賴於IntGenerator對象的EvenChecker任務都會測試它,以確定它是否被取消,如run()所示。

而且

例如,任務不能依賴於另一項任務,因爲任務 關機順序是不能保證。 在這裏,通過使任務取決於一個 非任務對象,我們消除潛在的競爭條件

如何理解?

public abstract class IntGenerator { 
    private volatile boolean canceled = false; 
    public abstract int next(); 
    public void cancel() { canceled = true; } 
    public boolean isCanceled() { return canceled; } 
} 

public class EvenChecker implements Runnable { 
    private IntGenerator generator; 
    private final int id; 
    public EvenChecker(IntGenerator g, int ident) { 
    generator = g; 
    id = ident; 
    } 
    public void run() { 
    while(!generator.isCanceled()) { 
     int val = generator.next(); 
     if(val % 2 != 0) { 
     System.out.println(val + " not even!"); 
     generator.cancel(); 
     } 
    } 
    } 
    // ... 
} 
+0

解釋很不明確 - 如果你對併發感興趣,我會建議找一本更好的書。 (我還會注意到,在99%的情況下,沒有理由有一個布爾標誌來取消任務--Java提供了一個本地中斷機制)。 – assylias

回答

1

當兩個或多個任務並行啓動,並根據其任務是第一位的,導致你的程序有不同的反應,inexpectedly甚至發生崩潰競爭狀態。如果沒有適當的預防措施(例如ExecutorService),則無法完全控制訂單,因爲底層操作系統總是最後決定的。

例如。你有一個

ArrayList<String> listA 

你有3個獨立的Runnables。

  • Runnable A應該向該列表中添加20個字符串。
  • Runnable B必須將它們全部設置爲小寫。
  • Runnable C drop duplicate。

平行啓動會導致混亂。

也許是想要的訂單。然後預期的結果將是一個沒有重複的列表,並且所有的字符串都是小寫字母。

但是如果Runnable C第一個出現,甚至B比A快呢?

然後你的listA既不會有重複,也不會把你的字符串變成小寫。

這是什麼種族情況通常是關於。 (用簡單的話說)

所以回到你的例子。

如果IntGenerator也是一個Runnable,你肯定會遇到很多麻煩來協調兩個Runnable之間的正確交互。我不會說那是不可能的,但是很麻煩。