当前位置: 首页 > 知识库问答 >
问题:

锁定中断与锁定

徐博雅
2023-03-14

我看不出有什么区别。我读到了这篇文章:actual-use-of-lockinterruptbly-for-a-reentrantlock

想测试一下。代码如下:

public class Test {
public static void main(String[] args){
    Test test = new Test();
    test.inturreptWork();
    //Main group
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getName());
    //System group  is the parent of main group. it contains system level threads like finalizer,signal dispatcher,attach listener
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getParent());
}

public void inturreptWork(){
    Inturrept inturrept= new Inturrept();
    Thread t1 = new Thread(inturrept,"Thread 1");
    Thread t2 = new Thread(inturrept,"Thread 2");
    Thread t3 = new Thread(inturrept,"Thread 3");
    try{
    t1.start();
    Thread.sleep(1000);
    t2.start();
    Thread.sleep(1000);
    t2.interrupt();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally {
        System.out.println("Finally");
    }


}

这里是Inturrept班

        public class Inturrept implements Runnable {
    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
            lock.lock();// or   lock.lockInterruptibly();

            System.out.println("Running");
            Thread.sleep(7000);// Use something else to mimic sleep as it throws interrupted exception 
            lock.unlock();// This caused IllegalMonitorStateException 
        } catch (InterruptedException e) {
            System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

控制台输出:

Trying to get lock ,Thread name is: Thread 1
Running
Trying to get lock ,Thread name is: Thread 2
Trying to get lock ,Thread name is: Thread 3
Running
Exception in thread "Thread 1" I was inturrepted, Thread name is: Thread 2
java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.test.main.Inturrept.run(Inturrept.java:15)
    at java.lang.Thread.run(Thread.java:748)
Running
Exception in thread "Thread 3" Finallyjava.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)

Main Thread group: main
Main Thread group: java.lang.ThreadGroup[name=system,maxpri=10]

正如回答中提到的“这与常规锁()相同。但如果另一个线程中断,等待的线程lockInterruptbly()将抛出InterruptedException。”即使它是锁着的。lock()或lock。LockInterruptbly()。线程被中断。那么有什么区别呢?我理解错了吗?请帮忙。还有一个问题是,为什么我在控制台中看到“线程中的异常”线程3。它运行时,我可以在日志中看到两个“运行”。

谢谢你。

共有1个答案

姚培
2023-03-14

lockInterruptbly()首先检查线程是否中断。如果中断,则抛出中断异常

 if (Thread.interrupted())
            throw new InterruptedException();
        if (!tryAcquire(arg))
            doAcquireInterruptibly(arg);

lock.unlock()在你的代码中调用了两次。所以它抛出IllegalMonitor orStateException,因为不是同一个线程在解锁。当线程在没有锁的情况下解锁时,它会抛出异常。

 if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();

线导致中断异常的睡眠。睡眠方法抛出中断异常

void sleep(long millis) throws InterruptedException

修改代码

 public void run() {
try {
    System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
    lock.lock();
    System.out.println("Running");
    //Thread.sleep(7000);

} catch (Exception e) {
    System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
    e.printStackTrace();
} finally {
    lock.unlock();
}

}

 类似资料:
  • 问题内容: 我在这里思考:如果您有2个线程执行需要同步的FAST操作,那么非阻塞方法不是比阻塞/上下文切换方法更快/更好的方法吗? 非阻塞的意思是: while(true){如果(checkAndGetTheLock())中断;} 如果您有太多线程在锁中循环,我唯一想到的就是饥饿(CPU耗尽)。 如何平衡一种方法与另一种方法? 问题答案: 以下是 Java Concurrency in Pract

  • 本文向大家介绍Eclipse操作SVN时中断锁定,文件的解锁方法,包括了Eclipse操作SVN时中断锁定,文件的解锁方法的使用技巧和注意事项,需要的朋友参考一下 Eclipse中,打开文件所在包,点击 "清理", 然后先锁定,后解锁:首先用自己的帐号选择 team-锁定(最重要的是要选择“强制解锁”选项),选择 team-解锁。 遇到SVN清理失败 并且报is not a working cop

  • 锁定 Subversion的拷贝-修改-合并版本控制模型的关键是其合并算法,也就是如何处理多个用户修改同时修改一个文件产生冲突时的算法。Subversion本身只提供了一个这样的算法,其三方区别算法可以足够聪明的的行粒度的数据处理,Subversion也支持使用外置比较工具(“外置 diff3”一节中有描述),有一些可以做得非常好,或许可以提供以单词或字母粒度的算法。但是,这些工具的共同点是基于文

  • 我正在编写一个应用程序来管理或自定义Android设备的解锁屏幕。它的工作原理如下: 用户使用电源按钮锁定屏幕。 用户尝试解锁屏幕,从而再次按下电源按钮 我的活动弹出--屏幕仍然锁定 用户回答问题,如果答案正确,屏幕解锁 我已经为第三步创建了一个活动,并将以下代码添加到其方法中: 这工作正常,完全符合我的期望。我的问题是第四步。我已经搜索并找到了许多解决方案,但没有一个适合我。 如何以编程方式锁定

  • 问题内容: 我正在阅读《 实践Java并发 》一书。在第15章中,他们讨论了非阻塞算法和 比较交换 (CAS)方法。 据记载,CAS的性能比锁定方法好得多。 我想问一下已经使用这两个概念的人,并想听听您何时更喜欢这些概念中的哪一个? 真的那么快吗? 对我来说,锁的用法更加清晰,易于理解,甚至维护起来也更好 (如果我错了,请纠正我) 。我们是否应该真正专注于创建与CAS相关的并发代码,而不是锁定,以

  • 问题内容: 我对事务与锁定表有些困惑,以确保数据库完整性,并确保SELECT和UPDATE保持同步,并且没有其他连接干扰它。我需要: 我需要确保没有其他查询会干扰并执行相同的操作(在该连接完成更新行之前读取“旧值”。 我知道我可以默认为只确保一次只有1个连接正在执行此操作,并在完成后将其解锁,但这似乎有点过头了。将它包装在事务中是否会做同样的事情(确保没有其他连接会尝试同一进程而另一个仍在处理)?