3
我需要一種方法來只允許一個線程修改與服務票據相關的數據。不止一個線程可能試圖同時修改票證數據。基於ID的線程同步
下面是我的方法的簡化版本。有一個更好的方法嗎?也許與java.util.concurrent包?
public class SomeClass1
{
static final HashMap<Integer, Object> ticketLockMap = new HashMap<Integer, Object>();
public void process(int ticketNumber)
{
synchronized (getTicketLock(ticketNumber))
{
// only one thread may modify ticket data here
// ... ticket modifications here...
}
}
protected static Object getTicketLock(int ticketNumber)
{
Object ticketLock;
// allow only one thread to use map
synchronized (ticketLockMap)
{
ticketLock = ticketLockMap.get(ticketNumber);
if (ticketLock == null)
{
// first time ticket is locked
ticketLock = new Object();
ticketLockMap.put(ticketNumber, ticketLock);
}
}
return ticketLock;
}
}
此外,如果我不希望HashMap中填充了未使用的鎖呢,我需要像下面這樣的更復雜的方法:
public class SomeClass2
{
static final HashMap<Integer, Lock> ticketLockMap = new HashMap<Integer, Lock>();
public void process(int ticketNumber)
{
synchronized (getTicketLock(ticketNumber))
{
// only one thread may modify ticket data here
// ... ticket modifications here...
// after all modifications, release lock
releaseTicketLock(ticketNumber);
}
}
protected static Lock getTicketLock(int ticketNumber)
{
Lock ticketLock;
// allow only one thread to use map
synchronized (ticketLockMap)
{
ticketLock = ticketLockMap.get(ticketNumber);
if (ticketLock == null)
{
// first time ticket is locked
ticketLock = new Lock();
ticketLockMap.put(ticketNumber, ticketLock);
}
}
return ticketLock;
}
protected static void releaseTicketLock(int ticketNumber)
{
// allow only one thread to use map
synchronized (ticketLockMap)
{
Lock ticketLock = ticketLockMap.get(ticketNumber);
if (ticketLock != null && --ticketLock.inUseCount == 0)
{
// lock no longer in use
ticketLockMap.remove(ticketLock);
}
}
}
}
class Lock
{
// constructor/getters/setters omitted for brevity
int inUseCount = 1;
}
您應該能夠使用'ConcurrentHashMap'而不是'HashMap'來解決票證鎖定問題,並避免執行不良的'synchronized'位。 'putIfAbsent()'應該正是你所需要的。 – manub
@Jeff檢查這個線程http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value –