我的班级有以下锁定机制。当我运行这个程序时,一个线程不断地获取并重新获取锁,而没有给任何其他线程获取锁的机会,从而导致饥饿。如何重构我的锁定机制,以便一旦一个线程放弃锁定,另一个线程获取它?我希望看到其他线程获得锁,而不必等到拥有锁的线程停止运行。
private final ReentrantLock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private final Map<Integer, Long> locksMap = new HashMap<Integer, Long>();
/** {@inheritDoc} */
@Override
public long lock(int recNo) throws RecordNotFoundException {
ValidationUtils.checkNegative(recNo);
lock.lock();
long id = Thread.currentThread().getId();
try {
while (locksMap.get(recNo) != null) {
try {
System.out.println("Thread " + id + " is waiting.");
condition.await();
}
catch (InterruptedException e) {
LOGGER.log(Level.SEVERE, e.getMessage());
return -1;
}
}
Long prevValue = locksMap.put(recNo, id);
if (prevValue != null) {
String msg = "Expected no value for " + recNo + " but was ";
msg += prevValue + ".";
throw new IllegalStateException(msg);
}
System.out.println("Thread " + id + " has the lock.");
}
finally {
lock.unlock();
}
return id;
}
/** {@inheritDoc} */
@Override
public void unlock(int recNo, long cookie) throws RecordNotFoundException, SecurityException {
ValidationUtils.checkNegative(recNo);
if (cookie < 0) {
throw new IllegalArgumentException("cookie is negative.");
}
lock.lock();
try {
if (locksMap.get(recNo) == cookie) {
locksMap.remove(recNo);
}
else {
String msg = "Wrong lock cookie. Expected " + locksMap.get(recNo);
msg += ", was " + cookie + ".";
throw new IllegalStateException(msg);
}
long id = Thread.currentThread().getId();
System.out.println("Thread " + id + " no longer has the lock.");
condition.signalAll();
}
finally {
lock.unlock();
}
}
/**
* Tests the locking mechanism in this class.
*
* @param args None.
*/
public static void main(String... args) {
ExecutorService threadPool = Executors.newFixedThreadPool(5);
final CountDownLatch latch = new CountDownLatch(5);
final Data data = new Data();
Runnable task = new Runnable() {
@Override
public void run() {
try {
for (int index = 0; index < 10; index++) {
long cookie = data.lock(1);
Thread.sleep(1000); // Do something.
data.unlock(1, cookie);
}
}
catch (SecurityException e) {
e.getStackTrace();
}
catch (RecordNotFoundException e) {
e.getStackTrace();
}
catch (InterruptedException e) {
e.getStackTrace();
}
finally {
latch.countDown();
}
}
};
for (int index = 0; index < 5; index++) {
threadPool.execute(task);
}
try {
latch.await();
}
catch (InterruptedException e) {
e.getStackTrace();
}
threadPool.shutdown();
}
这是输出。请注意,线程 9 仅在循环完成后才会停止获取锁。
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 9 has the lock.
Thread 13 is waiting.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 9 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 13 has the lock.
Thread 12 is waiting.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 13 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 12 has the lock.
Thread 11 is waiting.
Thread 10 is waiting.
Thread 12 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 11 has the lock.
Thread 10 is waiting.
Thread 11 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.
Thread 10 has the lock.
Thread 10 no longer has the lock.