पर लॉक का इंतजार करने के लिए के साथ syncronized
ब्लॉक को प्रतिस्थापित करना चाहता हूं।लॉक का उपयोग करते समय IllegalMonitorStateException से कैसे बचें Reentrantlock
private ReentrantLock lock = new ReentrantLock();
try
{
lock.lockInterruptably();
}
catch(InterruptedException e)
{
Thread.currentThread.interrupt();
}
finally
{
lock.unlock();
}
समस्या यह है कि अंत में बिल्कुल भी होता है जब InterruptedException होता है: इस के लिए, मैं lockInterruptibly()
विधि और मुहावरेदार ट्राई/अंत में ब्लॉक का उपयोग करें। इसका परिणाम 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();
}
}
}
}
यह प्रिंट इस उत्पादन:
START Taking lock on thread Thread-1 Trying to take lock on thread main java.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
क्या सबसे अच्छा तरीका है पर कोई विचार इस से बचने के लिए है?
कोई भी डाउनवोट पर टिप्पणी करने की परवाह करता है? – jtahlborn
मैं पहले 'isHeldByCurrentThread' का उपयोग कर रहा था, लेकिन सभी टिप्पणियों को पढ़ने के बाद, मुझे लगता है कि यह संस्करण केवल एकमात्र है जो वास्तव में सही है। –
@WimDeblauwe आप किस टिप्पणी का जिक्र कर रहे हैं, और आप क्यों सोचते हैं कि 'isHeldByCurrentThread' सही नहीं है? –