我正在尝试理解LockSupport.java,并参考了它的文档。在那里,它有代码片段,其中作者提供了使用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启动并获取锁,然后Thread-2调用unlock()。Main调用lock()。我的理解是,Main将永远被阻塞,即使线程-2调用了unlock(),因为线程-2从未调用过permit()(因此,它永远不会被授予锁)。
我不能理解这种行为。如果我在Thread-2中注释unlock(),那么main-thread将永远被阻塞。
一个线程(在我的例子中是Thread-2)调用unlock() (它以前没有调用lock()),而其他线程(在这个例子中是主线程)调用lock(),但从未被锁定,这是怎么可能的呢?
发布于 2021-01-30 18:49:55
如果深入研究源代码,unblock方法实际上会释放变量locked提供的CAS锁,并解除第一线程的驻留。因此,如果注释掉unlock()的调用,CAS锁不会被释放,并且主线程可能永远停留在while循环中,这会阻塞主线程。
发布于 2021-01-30 21:00:28
首先: FIFOMutex调用
Thread current = Thread.currentThread();这意味着实际的线程被用于验证。这意味着考虑最实际的线程,也就是:
首先是
这就是为什么主线程不会挂起的原因。但是:如果您注释线程2的解锁,则没有执行任何操作,并且主线程挂起。这是很容易理解的,不是吗?
https://stackoverflow.com/questions/62396551
复制相似问题