- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想用 ReentrantLock
替换 syncronized
block 以支持中断等待锁。为此,我使用了 lockInterruptibly()
方法和惯用的 try/finally block :
private ReentrantLock lock = new ReentrantLock();
try
{
lock.lockInterruptably();
}
catch( InterruptedException e )
{
Thread.currentThread.interrupt();
}
finally
{
lock.unlock();
}
问题是 finally 当然也会在 InterruptedException 发生时发生。这会导致 IllegalMonitorStateException
,因为当前线程未持有锁。
这个简单的程序证明了这一点:
public class LockTest
{
public static void main( String[] args )
{
System.out.println("START");
Thread interruptThread = new Thread( new MyRunnable( Thread.currentThread() ) );
interruptThread.start();
ReentrantLock lock = new ReentrantLock();
Thread takeLockThread = new Thread( new TakeLockRunnable( lock ) );
takeLockThread.start();
try
{
Thread.sleep( 500 );
System.out.println("Trying to take lock on thread " + Thread.currentThread().getName());
lock.lockInterruptibly();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally {
lock.unlock();
}
System.out.println( "DONE");
}
private static class MyRunnable implements Runnable
{
private Thread m_thread;
private MyRunnable( Thread thread)
{
m_thread = thread;
}
@Override
public void run()
{
try
{
Thread.sleep( 1000 );
}
catch (InterruptedException e)
{
// ignore
}
System.out.println( "Interrupting thread " + m_thread.getName() );
m_thread.interrupt();
}
}
private static class TakeLockRunnable implements Runnable
{
private ReentrantLock m_lock;
public TakeLockRunnable( ReentrantLock lock )
{
m_lock = lock;
}
@Override
public void run()
{
try
{
System.out.println("Taking lock on thread " + Thread.currentThread().getName());
m_lock.lock();
Thread.sleep( 20000 );
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
m_lock.unlock();
}
}
}
}
它打印这个输出:
STARTTaking lock on thread Thread-1Trying to take lock on thread mainjava.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:877) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1201) at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:312) at LockTest.main(LockTest.java:25) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)Exception in thread "main" java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:127) at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1239) at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:431) at LockTest.main(LockTest.java:32) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)Interrupting thread main
知道避免这种情况的最佳方法是什么吗?
最佳答案
lockInterruptibly()
调用应该在 finally block 的外部。请注意,这总是尝试使用 Lock
API(无论您使用 lock()
还是 lockInterruptibly()
),因为您 除非您已获得锁,否则不想进行“解锁”工作。
try {
lock.lockInterruptibly();
try {
// do locked work here
} finally {
lock.unlock();
}
} catch( InterruptedException e ) {
Thread.currentThread.interrupt();
}
关于java - 在 Reentrantlock 上使用 lockInterruptibly 时如何避免 IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8897449/
我是 Java 新手(也是 RoR 开发人员)。 我有一个简单的程序。球由球员共享。球应传给随机玩家。 好的,代码如下: class Ball { private int currentPl
我是否没有正确使用同步: 在下面的代码中我遇到了两个问题: 1.在将方法(designBusiness、createBusiness、sellBusiness)设置为 synchronized 时,就
我不完全理解wait和notify(Object)是如何工作的,结果我被迫瘦身将我的尝试记入以下代码部分。 Main.java: import java.util.ArrayList; class M
我有这个代码 if( id == 0 ||(id % 2) != 0){ System.out.println("test"); synchronized(lo
我是 Java 新手。我刚刚读了《java核心》这本书。我遇到了有关“条件和锁定”的问题。 我从书上敲了一段代码到eclipse中做了一些练习。 当我运行代码时,“sufficientFund.wai
我想模拟一个妈妈叫三个 child 吃饭,这是我的代码: class child extends Thread{ String name; mother mom; public
我正在尝试在新线程中调用方法,该方法将在使用 callable 延迟后返回一些东西。由于,它正在下降IllegalMonitorStateException 当我只创建类的实例,调用方法并且该方法将延
我已经使用 java 线程构建了生产者-消费者。生产者和消费者是两个不同的类,指的是单链表和对象锁。下面的实现有什么问题? Item Produced by Thread-0 Item 1 Item
我在我的代码中遇到了 IllegalMonitorStateException,我不确定为什么会收到它以及如何修复它。我当前的代码是并且错误发生在 try block 中: public stat
请向我解释为什么我的代码在等待函数中抛出 IllegalMonitorStateException ,据我所知,只有在同步部分未完成时才会发生这种情况? private void deliver(in
每当我调用pauseThread()时,它总是抛出IllegalMonitorStateException。 我在文档中注意到我需要拥有对象监视器才能使线程等待。 用这段代码 synchronized
我正在尝试学习java并发编程。请检查我的示例代码并帮助我理解为什么我会收到“java.lang.IllegalMonitorStateException”,即使我在同步上下文中调用了 wait()
我对监视器和条件变量不熟悉。我在监视器中使用锁定和条件变量。 public class Monitor { private final int piNumberOfPhilosopher
所以我正在尝试编写一个程序来打印出以下输出: 44 33 22 11 该程序应该是多线程的,并且必须使用锁来防止竞争条件。它还必须利用 Condition,以便当线程想要打印的数字与变量 thread
我对多线程了解甚少。 我期望下面的程序能够完美运行,但它不起作用并产生以下异常。 Exception in thread "Thread-1" java.lang.IllegalMonitorStat
我不完全理解wait和notify(Object的)的工作方式,因此,我不得不将尝试减少到以下代码部分。 Main.java: import java.util.ArrayList; class
void waitForSignal(){ Object ob =new Object(); synchronized (Thred.currentThread()) {
我收到一个 IllegalMonitorStateException,我觉得我无法阅读更多内容,所以我问是否有人知道我做错了什么。在计数器(门类中线程之间的共享资源)陷入等待状态后,我在程序运行结束时
我有一个程序可以模拟一艘船的大门。它们在线程中运行。这个想法是让它们在 run 方法中的随机时刻运行和暂停,以模拟路过的人。这是由所有线程完成的,同时主线程正在等待通知并检查船是否已满,当线程通知他们
我想在线程中运行的 Vector 中使用同步 我尝试使用两种方法,一种用于等待,另一种用于通知 我想从静态类调用notify方法这是我的线程代码: import java.io.IOException
我是一名优秀的程序员,十分优秀!