您实际使用这种方法是lockInterruptibly
什么?我已经阅读了API,但是对我来说不是很清楚。有人可以用其他语言表达吗?
5 回答
lockInterruptibly()
如果锁已被另一个线程持有,则可能会阻塞,并将等待直到获得锁。这与常规相同lock()
。但如果另一个线程中断等待线程 lockInterruptibly()
将抛出InterruptedException
.
逻辑与所有可中断阻塞方法的逻辑相同:它允许线程立即对interrupt
从另一个线程发送给它的信号作出反应。
如何使用此特定功能取决于应用程序设计。例如,它可以用来杀死池中所有等待获取锁的线程队伍。
尝试通过下面的代码示例来理解这个概念。
代码示例:
package codingInterview.thread;
import java.util.concurrent.locks.ReentrantLock;
public class MyRentrantlock {
Thread t = new Thread() {
@Override
public void run() {
ReentrantLock r = new ReentrantLock();
r.lock();
System.out.println("lock() : lock count :" + r.getHoldCount());
interrupt();
System.out.println("Current thread is intrupted");
r.tryLock();
System.out.println("tryLock() on intrupted thread lock count :" + r.getHoldCount());
try {
r.lockInterruptibly();
System.out.println("lockInterruptibly() --NOt executable statement" + r.getHoldCount());
} catch (InterruptedException e) {
r.lock();
System.out.println("Error");
} finally {
r.unlock();
}
System.out.println("lockInterruptibly() not able to Acqurie lock: lock count :" + r.getHoldCount());
r.unlock();
System.out.println("lock count :" + r.getHoldCount());
r.unlock();
System.out.println("lock count :" + r.getHoldCount());
}
};
public static void main(String str[]) {
MyRentrantlock m = new MyRentrantlock();
m.t.start();
System.out.println("");
}
}
输出:
lock() : lock count :1
Current thread is intrupted
tryLock() on intrupted thread lock count :2
Error
lockInterruptibly() not able to Acqurie lock: lock count :2
lock count :1
lock count :0
根据Evgeniy Dorofeev 的回答,我只是故意想出了这样的演示,但我真的不知道到底在哪里,可以使用它。也许这个演示可以帮助一点点:)
private static void testReentrantLock() {
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(() -> {
int i = 0;
System.out.println("before entering ReentrankLock block");
try {
lock.lockInterruptibly();
while (0 < 1) {
System.out.println("in the ReentrankLock block counting: " + i++);
}
} catch (InterruptedException e) {
System.out.println("ReentrankLock block interrupted");
}
});
lock.lock(); // lock first to make the lock in the thread "waiting" and then interruptible
thread.start();
thread.interrupt();
}
输出
before entering ReentrankLock block
ReentrankLock block interrupted
使用的线程lockInterruptibly()
可以被另一个线程中断。因此,调用可以捕获的lockInterruptibly()
throws InterruptedException
,并且可以在 catch 块中完成有用的事情,例如释放持有的锁,以便导致中断发生的其他线程可以访问已释放的锁。考虑一下您有一个具有以下读写约束的通用数据结构的情况:
- 单个线程负责写入公共数据结构。
- 有一个读者线程。
- 正在进行写入时,不应允许读取。
为了满足上述限制,读者线程可以使用lockInterruptibly()
来获得对java.util.concurrent.locks.ReentrantLock
. 这意味着读线程可以在写线程处理期间随时中断。写线程可以访问读线程实例,写线程可以中断读线程。当阅读器收到中断时,在 的 catch 块中 InterruptedException
,阅读器应unlock
保持ReentrantLock
并等待来自编写器线程的通知以继续进行。写线程可以使用tryLock
方法获取相同的锁。下面给出了读取器和写入器线程的代码片段:
读取器和写入器线程访问的公共字段:
ReentrantLock commonLock = new ReentrantLock(); //This is the common lock used by both reader and writer threads.
List<String> randomWords = new ArrayList(); //This is the data structure that writer updates and reader reads from.
CountDownLatch readerWriterCdl = new CountDownLatch(1); //This is used to inform the reader that writer is done.
读者:
try {
if(!commonLock.isHeldByCurrentThread())
commonLock.lockInterruptibly();
System.out.println("Reader: accessing randomWords" +randomWords);
} catch (InterruptedException e) {
commonLock.unlock();
try {
readerWriterCdl.await();
}
catch (InterruptedException e1) {
}
}
作家:
if(commonLock.isLocked() && !commonLock.isHeldByCurrentThread())
{
readerThread.interrupt();
}
boolean lockStatus = commonLock.tryLock();
if(lockStatus) {
//Update the randomWords list and then release the lock.
commonLock.unlock();
readerWriterCdl.countDown();
readerWriterCdl = new CountDownLatch(1);
}