【发布时间】:2020-06-15 20:36:28
【问题描述】:
我试图了解LockSupport.java 并参考了它的文档。在那里,它有代码 sn-p,其中作者提供了使用 LockSupport#park() 和 LockSupport#Unpark() 实现互斥锁的示例。
我使用该示例并创建了一个使用该示例 FIFOMutex 的程序。
FIFOMutex 代码(取自 LockSupport.java)
package com.example.java.locking.studies.locksupport.from.javadoc;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean(false);
private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
public void lock() {
boolean wasInterrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
// Block while not first in queue or cannot acquire lock
while (waiters.peek() != current ||
!locked.compareAndSet(false, true)) {
LockSupport.park(this);
if (Thread.interrupted()) // ignore interrupts while waiting
wasInterrupted = true;
}
waiters.remove();
if (wasInterrupted) // reassert interrupt status on exit
current.interrupt();
}
public void unlock() {
locked.set(false);
LockSupport.unpark(waiters.peek());
}
}
现在,我编写了下面的程序来使用FIFOMutex作为锁定机制,代码如下:
package com.example.java.locking.studies.locksupport.from.javadoc;
public class FIFOMutexMainApp {
public static void main(String[] args) throws InterruptedException {
FIFOMutex mutex = new FIFOMutex();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Inside thread -> " + Thread.currentThread() + "Before mutex.lock()");
mutex.lock();
System.out.println("Inside thread -> " + Thread.currentThread() + "After mutex.lock()");
for (;;) {
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Inside thread -> " + Thread.currentThread() + "Before mutex.lock()");
mutex.unlock();
System.out.println("Inside thread -> " + Thread.currentThread() + "After mutex.lock()");
for (;;) {
}
}
});
t1.start();
Thread.sleep(10);
t2.start();
Thread.sleep(100);
mutex.lock();
System.out.println("Inside thread -> " + Thread.currentThread() + "will I get printed?");
}
}
下面是这个程序的输出:
Inside thread -> Thread[Thread-0,5,main]Before mutex.lock()
Inside thread -> Thread[Thread-0,5,main]After mutex.lock()
Inside thread -> Thread[Thread-1,5,main]Before mutex.lock()
Inside thread -> Thread[Thread-1,5,main]After mutex.lock()
Inside thread -> Thread[main,5,main]will I get printed?
Thread-1 启动并获取锁,随后是调用 unlock() 的 Thread-2。主要调用 lock()。我的理解是 Main 将永远被阻塞,即使 Thread-2 调用了 unlock(),因为 Thread-2 从未调用 lock()(因此,它从未被授予 permit)。
我无法理解这种行为。如果我在 Thread-2 中注释 unlock(),那么主线程将永远被阻塞。
一个线程(在我的情况下是 Thread-2)怎么可能调用 unlock()(以前没有调用 lock())而其他线程(在这种情况下是主线程)调用 lock(),但从来没有被锁了?
【问题讨论】:
标签: java multithreading mutex locks