2012-10-09 54 views
-1

我的程序有一個無死鎖的條件。 ResourceManager將 (Set<ResourceNames, long ID>) 中的客戶端寫入/讀取(布爾型爲true/false)。 這是一種方法static long getLock(Set<String> resources, boolean operation)static void releaseLock(long ID)使我的資源管理器成爲「無死鎖」

所有的資源都是1-1。如果資源用於寫入,則該資源不適用於另一個目標。如果要讀取,其他客戶端可以只讀取,不寫入。 資源名稱是Strings.While ResourceManager無法爲客戶端提供資源,但必須在getlock()方法中阻止該資源,並在資源可用於客戶端時返回。

getlock()方法使用資源並創建一個ID,而relaselock()方法從ID解放資源。我的任務是編寫ResourceManager,它將是無死鎖的。

客戶端類爲隨機操作和資源創建k客戶端,並啓動它。這門課是寫的,但我看不到它。 我的任務是編寫一個類,以及這兩個方法。

- 問題是阻止客戶端並返回! -DeadLock - 免費

package itself.probafeladat14; 

import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.Random; 
import java.util.Set; 

public class ResourceManager { 

    protected static HashMap<String, Boolean> reservedResources = 
      new HashMap<String, Boolean>(); 
    protected static HashMap<Long, Set<String>> resourcesByID = 
      new HashMap<Long, Set<String>>(); 
    protected static LinkedList<Long> sequenceOfID = 
      new LinkedList<Long>(); 



    public static void releaseLock(long ID) { 
     boolean read = false; 
     Set<String> resources = resourcesByID.remove(ID); 
     sequenceOfID.remove(ID); 

     for (String str : resources) 
      if (reservedResources.containsKey(str)) { 
       if (reservedResources.get(str) == true) 
        reservedResources.remove(str); 
       else if (reservedResources.get(str) == false) { 
        for (long i : sequenceOfID) 
         if (resourcesByID.get(i).contains(str)) 
          read = true; 
        if (!read) 
         reservedResources.remove(str); 
        read = false; 
       } 
      } 
    } 


    public static long getLock(Set<String> resources, boolean operation) throws ResourceNotAvaliableException { 

     boolean isFree = true; 
     boolean uniqueID = false; 
     long ID = 0; 

     for (String str : resources) { 
      if (reservedResources.containsKey(str)) { 
       if (reservedResources.get(str)) { 
        isFree = false; 
       } 
       if (reservedResources.get(str) == false && 
         operation == true) { 
        isFree = false; 
       } 
      } 
     } 

     if (!isFree) 
      throw new ResourceNotAvaliableException(); 
     else { 
      for (String s : resources) 
       if (!reservedResources.containsKey(s)) 
        reservedResources.put(s, operation); 
      while (!uniqueID) { 
       ID = new Random().nextLong(); 
       if (!sequenceOfID.contains(ID)) 
        uniqueID = true; 
      } 
      sequenceOfID.addLast(ID); 
      resourcesByID.put(ID, resources); 
      return ID; 
     } 
    } 
} 

回答

1

我看不出你如何能得到死鎖與當前實現,但也有一些多線程與它的問題:收購時

  • 非原子行爲鎖(例如,如果我嘗試獲取A的鎖,然後嘗試同時獲取B和A的鎖,那麼這將失敗,但是然後嘗試獲取B的鎖也將失敗,因爲之前的操作對州進行了不正確的改變)。當他們不應該獲得
  • 鎖(如2個線程調用getLock()對同一資源由於時間檢查你的資源是否被鎖定,實際添加的資源集合之間的窗戶上都可以成功。
  • ConcurrentModificationException被拋出不可預測時2個線程試圖在同一時間更新相同的非線程安全的集合。

您可以通過同步某些方法解決一些問題,但你需要仔細這樣做是爲了一方面避免死鎖,另一方面使其成爲並行性瓶頸。

1

我會建議你在GETLOCK方法,而不是使用AtomicBoolean

 


     if (!reservedResources.containsKey(s)) { 
     reservedResources.get(s).set(operation); 
     } 

 

這將避免鎖定爲西蒙說,你將不再需要使用同步方法。

此外,我會做的所有'isFree'邏輯的方法的底部。 換句話說:

 



    for (String s : resources) { 
     if (reservedResources.containsKey(s)) { 
      if (reservedResources.get(s).get()) { 
       throw new ResourceNotAvaliableException(); 
      } 
      if (!reservedResources.get(s).get() && operation == true) { 
       throw new ResourceNotAvaliableException() 
      } 
     } 
    } 
    for (String s : resources) { 
     if (!reservedResources.containsKey(s)) 
      reservedResources.put(s, operation); 
    } 
    while (!uniqueID) { 
     ID = new Random().nextLong(); 
     if (!sequenceOfID.contains(ID)) 
      uniqueID = true; 
    } 
    sequenceOfID.addLast(ID); 
    resourcesByID.put(ID, resources); 
    return ID;