public static void lock() {
Lock lock = new ReentrantLock();
try {
lock.lock();
Thread t1 = new Thread(() -> {
Thread currentThread = Thread.currentThread();
try {
lock.lock();
System.out.println(currentThread.getName() + " lock后的代码");
} finally {
lock.unlock();
}
System.out.println("currentThread = " + currentThread.getName() + " isInterrupted:" + currentThread.isInterrupted());
}, "t1");
t1.start();
t1.interrupt();
System.out.println("currentThread = " + Thread.currentThread().getName());
} finally {
lock.unlock();
}
}
currentThread = main
t1 lock后的代码
currentThread = t1 isInterrupted:true
main线程把t1线程的中断标志位设置为true,t1线程拿到锁后继续执行(仅仅是这只了中断标识位)
public static void lockInterruptiblyDemo() {
Lock lock = new ReentrantLock();
try {
lock.lock();
Thread t1 = new Thread(() -> {
Thread currentThread = Thread.currentThread();
try {
lock.lockInterruptibly();
System.out.println(currentThread.getName() + " lockInterruptibly后的代码");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("currentThread = " + currentThread.getName() + " isInterrupted:" + currentThread.isInterrupted());
}, "t1");
t1.start();
t1.interrupt();
System.out.println("currentThread = " + Thread.currentThread().getName());
} finally {
lock.unlock();
}
}
currentThread = main
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at Xxx.lambda$lockInterruptiblyDemo$1(Xxx.java:39)
at java.lang.Thread.run(Thread.java:748)
Exception in thread "t1" 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 Xxx.lambda$lockInterruptiblyDemo$1(Xxx.java:44)
at java.lang.Thread.run(Thread.java:748)
获取锁之前会判断中断标志位,也就是说可以中断获取锁的线程并抛出异常.
为什么AQS中的链表要设计成双向链表?
排队等待锁,需要修改前一个节点的状态
唤醒锁的时候:从头结点往后遍历