2014-10-17 91 views
0

我有一個數組,這2個值,我想保持單元格獨立。例如,當一個線程獲得第一個位置的鎖定時,這個線程不會阻塞整個結構。鎖定數組的單元格

public DataStructure(int r, int i) { 
     this.r = r; 
     this.i = i; 
     values = new ArrayList<Integer>; 
     values.add(i); 
     values.add(r); 
     [...] 
} 
public void methodA() { 
     lock.lock(); 
      [...] 
      values.get(0); 
      lock.unlock();  
} 
public void methodB() { 
     lock.lock(); 
      [...] 
      values.get(1); 
      lock.unlock();  
} 

與此代碼當一個線程獲取有關methodA這是不可能到一個不同的線程來獲得methodB鎖的鎖。

我該怎麼辦呢?

+0

你的意思是說你的方法應該是'synchronized'嗎? – 2014-10-17 08:50:14

+0

@ShishirKumar不,我的意思是說,如果一個線程訪問數組的第一個位置,另一個線程可以訪問其他位置,沒有同步,但具有並行性 – 2014-10-17 08:51:55

+0

哦,我現在明白了。 – 2014-10-17 08:53:00

回答

1

您需要爲每個單元格設置一個鎖定對象。如果你永遠只能有兩個值,則有

Object lock1 = new Object(); 
Object lock2 = new Object(); 

在類的標題,然後方法的聲明synchronized塊使用鎖1和的methodB有使用鎖2 synchronized塊都有。然後每個「單元格」被獨立鎖定。

例如

public void methodA() { 
    synchronized(lock1) { 
     [...] 
     values.get(0); 
     } 
} 

public void methodB() { 
    synchronized(lock2) { 
     [...] 
     values.get(1); 
     } 
} 

如果你將有很多獨立的細胞,那麼爲什麼不宣佈哪些有鎖在裏面,並且用作包裝的每個單元格的值的單元格類。然後你可以有一個更一般的方法來訪問一個線程安全的單元格的內容。

例如

class Cell { 
    private Object lock; 
    private Object value; 

    public void doSomething() { 
     synchronized(lock) { 
      // something happens here with the value 
     } 
    } 
} 

但是,目前還不清楚在線程安全方面您會從中獲得什麼。

+0

謝謝你的回答,你能否給我提供一個小段子,我有點困惑。 – 2014-10-17 08:55:09

+0

我會把它放在帖子中。 – 2014-10-17 08:56:46

1

如果您想爲陣列中的每個元素分別設置一個鎖,您可以使用一組Lock對象來匹配其他陣列,並依次鎖定每個單元。

或者,您可以考慮使用其中一個併發集合,例如CopyOnWriteArrayListConcurrentHashMap,具體取決於您的需要。

這些集合是線程安全的併爲您處理鎖定。

+0

「併發集合」在這裏會有幫助嗎?如果程序需要鎖定對某個集合中某個特定成員的訪問權限,那麼無論該集合對象本身是否爲線程安全的,都需要該鎖定。線程安全性是不可編輯的:如果您完全使用線程安全組件構建程序,那麼它本身並不會使您的程序線程安全。 – 2014-10-17 15:20:38

1

從我所瞭解的問題來看,java.util.concurrent中的併發列表實現可能對您有所幫助。

你應該在這個包中尋找CopyOnWriteArrayList類。

請參閱前面的SO問題,它可以很好地解釋它。

https://stackoverflow.com/a/10397154/2867032

CopyOnWriteArrayList類是一個有趣的案例。它避免了只讀操作(如get和 包含)中的併發瓶頸,但它通過在更改 操作以及修改可見性規則方面做了大量工作。此外,變異操作鎖定整個列表,因此是併發瓶頸。這些屬性意味着 CopyOnWriteArrayList不能稱爲通用併發 列表。

希望這可以幫助你。

+0

問題更新,我不能創建更多的對象實例,我必須只與一個對象實例一起工作。 – 2014-10-17 09:02:06