17

您实际使用这种方法是lockInterruptibly什么?我已经阅读了API,但是对我来说不是很清楚。有人可以用其他语言表达吗?

4

5 回答 5

13

lockInterruptibly()如果锁已被另一个线程持有,则可能会阻塞,并将等待直到获得锁。这与常规相同lock()。但如果另一个线程中断等待线程 lockInterruptibly()将抛出InterruptedException.

于 2013-07-23T13:59:08.947 回答
7

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

如何使用此特定功能取决于应用程序设计。例如,它可以用来杀死池中所有等待获取锁的线程队伍。

于 2013-07-23T13:55:10.790 回答
1

尝试通过下面的代码示例来理解这个概念。

代码示例:

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
于 2018-08-21T02:56:21.523 回答
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
于 2019-05-19T10:46:50.250 回答
0

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

  1. 单个线程负责写入公共数据结构。
  2. 有一个读者线程。
  3. 正在进行写入时,不应允许读取。

为了满足上述限制,读者线程可以使用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);
}
于 2021-08-03T09:12:54.243 回答