实际使用lockInterruptibly for ReentrantLock

时间:2013-07-23 13:26:38

标签: java concurrency locking reentrantlock

您对此方法[{1}}实际使用了什么?我已经阅读了API,但这对我来说并不是很清楚。换句话说,有人可以表达吗?

5 个答案:

答案 0 :(得分:8)

如果锁已被另一个线程持有,则

lockInterruptibly()可能会阻塞,并且会等到获取锁定为止。这与常规lock()相同。但是如果另一个线程中断,等待线程lockInterruptibly()将抛出InterruptedException

答案 1 :(得分:5)

逻辑与所有可中断的阻塞方法相同:它允许线程立即对从另一个线程发送给它的interrupt信号作出反应。

如何使用此特定功能取决于应用程序设计。例如,它可以用来杀死池中的一些线程,这些线程都在等待获取锁。

答案 2 :(得分:0)

尝试通过下面的代码示例了解这一概念。

代码示例:

array_push()

输出:

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("");
    }

}

答案 3 :(得分:0)

基于Evgeniy Dorofeev's answer,我只是故意提出了这样的演示,但我真的不知道可以在哪里使用它。也许这个演示可以帮助一点点:)

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

答案 4 :(得分:0)

使用 lockInterruptibly() 的线程可以被另一个线程中断。因此,对 lockInterruptibly() 的调用抛出可以被捕获的 InterruptedException,并且可以在 catch 块内完成有用的事情,例如释放持有的锁,以便导致中断发生的另一个线程可以获得访问释放的锁。想想您有一个具有以下读写约束的通用数据结构的情况:

<块引用>
  1. 单个线程负责写入公共数据结构。
  2. 只有一个读者线程。
  3. 在写入过程中,不应允许读取。

为了满足上述约束,阅读器线程可以使用 lockInterruptibly() 来访问 java.util.concurrent.locks.ReentrantLock。这意味着读取器线程可以在写入器线程的处理过程中随时被中断。写线程可以访问读线程实例,写线程可以中断读线程。当读取器接收到中断时,在 InterruptedException 的 catch 块中,读取器应该 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);
}