2017-08-27 21 views
1

我有一個多線程應用程序,我想在String上使用重入鎖。例如,如果我使用正常的同步,我的代碼將如下所示。如何獲取字符串值的重入鎖定?

我不希望兩個IP地址相同的IP地址在我的loadBalance()中輸入,所以我鎖定了IP地址,它工作正常。

class A { 
    String ipAddress; 
    ... 
    void loadBalance() { 
     synchronized (ipAddress) { 
      // Business logic goes here 
     } 
    } 
} 

現在,如果我使用重入API這裏,那麼代碼看起來像below.Now同一個IP地址的兩個線程在我的代碼不要求是進入。所以我需要知道如何使用Re-entrant API來防止這種情況。

class A { 
    String ipAddress; 
    ReentrantLock lock = new ReentrantLock(); 
    ... 
    void loadBalance() { 
     lock.lock(); 
      // Business logic goes here 
     lock.unlock(); 
    } 
} 

我的查詢是我怎麼能使用Re-entrant鎖鎖取IP地址,因爲我在synchronized block正在做的。

+0

不,我說我要採取鎖名稱IP地址。所以我很清楚,我怎樣才能實現使用同步塊。但我不知道如何使用重入API鎖定IP地址。如果我採取類似lock.lock()的操作,那麼兩個具有相同IP地址的線程將進入我的塊中,這是不推薦的。 –

+0

謝謝您的澄清 –

+0

歡迎您:)我希望您能分享您對此的寶貴意見。 –

回答

0

我找到了一個方法,但不知道這是否是正確的方法。 我已經找到了class,將提供針對String名字的鎖提供

import java.util.concurrent.ConcurrentHashMap; 
import java.util.concurrent.locks.ReentrantLock; 

public class LockByName<L> { 

    ConcurrentHashMap<String, L> mapStringLock; 

    public LockByName() { 
     mapStringLock = new ConcurrentHashMap<String, L>(); 
    } 

    public LockByName(ConcurrentHashMap<String, L> mapStringLock) { 
     this.mapStringLock = mapStringLock; 
    } 

    @SuppressWarnings("unchecked") 
    public L getLock(String key) { 
     L initValue = (L) createIntanceLock(); 
     L lock = mapStringLock.putIfAbsent(key, initValue); 
     if (lock == null) { 
      lock = initValue; 
     } 
     return lock; 
    } 

    protected Object createIntanceLock() { 
     return new ReentrantLock(); 
    } 

} 

class A { 
String ipAddressl 
    LockByName<ReentrantLock> reentrantLocker = new LockByName<ReentrantLock>(); 
    ... 
    ReentrantLock reentrantLock1 = reentrantLocker.getLock(ipAddress); 

    try { 
     reentrantLock1.lock(); 
     // DO WORK 

    } finally { 
     reentrantLock1.unlock(); 

    } 

} 
2

而不是讓每個String的鎖,這可能會導致鎖的不斷增長的量,最終可能的OutOfMemoryError,它的更好在這種情況下使用條形鎖定策略。 (如n),將它們存儲在數組中。如果您需要給定String的鎖,請使用其hashCode()和模n來確定哪個數組元素包含要使用的鎖。等於String s將使用相同的鎖。

private static final int N = 10; 
private ReentrantLock[] locks = new ReentrantLocks[N]; 

{ 
    for (int i = 0; i < N; i++) { 
     locks[i] = new ReentrantLock(); 
    } 
} 

... 

// where you need a lock : 
String ipAddress = ... 

ReentrantLock lock = locks[ipAddress.hashCode() % N]; 
lock.lock(); 

折衷是,一些不等於String s也會使用相同的鎖。您應該測試不同數量的n以在不需要的鎖爭用和內存之間取得平衡。

另外,您可以用番石榴的Striped