我无法弄清楚差异。我读到了这个:actual-use-of-lockinterruptibly-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 Class
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]
正如答案中所提到的“这与常规lock()相同。但是如果另一个线程中断了等待线程,lockInterruptibly()将抛出InterruptedException。” 即使它是lock.lock()或lock.lockinterruptibly()。线程被打断了。那有什么区别?我明白了什么不对请帮忙。 另外一个问题是我为什么在控制台中看到“线程中的异常”“线程3”。它可以在日志中看到两个“运行”。
谢谢你。
答案 0 :(得分:1)
lockInterruptibly()首先检查线程是否被中断。如果被中断则抛出InterruptedException
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
lock.unlock()在你的代码中调用了两次。所以它抛出IllegalMonitorStateException
,因为没有相同的线程正在解锁。当线程执行解锁而没有锁定时它会抛出异常。
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
Thread.sleep导致中断异常.Sleep方法抛出InterruptedException
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();
}
}