赞
踩
ReentrantLock初认知
AQS中可重入锁ReentrantLock源码一加锁过程
AQS中可重入锁ReentrantLock源码一释放锁过程
AQS中那些waitStatus(一)
AQS中那些waitStatus(二)
// CANCELLED:由于超时或中断,此节点被取消。节点一旦被取消了就不会再改变状态。特别是,取消节点的线程不会再阻塞。
static final int CANCELLED = 1;
// SIGNAL:此节点后面的节点已(或即将)被阻止(通过park),因此当前节点在释放或取消时必须断开后面的节点
// 为了避免竞争,acquire方法时前面的节点必须是SIGNAL状态,然后重试原子acquire,然后在失败时阻塞。
static final int SIGNAL = -1;
// 此节点当前在条件队列中。标记为CONDITION的节点会被移动到一个特殊的条件等待队列(此时状态将设置为0),直到条件时才会被重新移动到同步等待队列 。(此处使用此值与字段的其他用途无关,但简化了机制。)
static final int CONDITION = -2;
//传播:应将releaseShared传播到其他节点。这是在doReleaseShared中设置的(仅适用于头部节点),以确保传播继续,即使此后有其他操作介入。
static final int PROPAGATE = -3;
//0:以上数值均未按数字排列以简化使用。非负值表示节点不需要发出信号。所以,大多数代码不需要检查特定的值,只需要检查符号。
//对于正常同步节点,该字段初始化为0;对于条件节点,该字段初始化为条件。它是使用CAS修改的(或者在可能的情况下,使用无条件的volatile写入)。
从上面的注释介绍可以明白,只有上一个节点是SIGNAL,当前节点才有可能被上一个节点唤醒。
由于超时或中断,此节点被取消。节点一旦被取消了就不会再改变状态。特别是,取消节点的线程不会再阻塞。
从中断线程案例开始:
public class NonFairReentrantLock extends AbstractQueuedSynchronizer { public static void main(String[] args) { final ReentrantLock lock = new ReentrantLock(); List<Thread> threads = new ArrayList<>(10); for (int i = 0; i < 10; i++) { Thread thread = new Thread("线程: " + i) { @Override public void run() { try { lock.lockInterruptibly(); // 如果线程被中断了在这里会抛出异常 // ... method body System.out.println(Thread.currentThread().getName() + " 开始执行!"); Thread.sleep(100); System.out.println(Thread.currentThread().getName() + " 执行结束!"); } catch (InterruptedException e) { // 这里处理线程中断的后续逻辑 System.out.println(Thread.currentThread().getName() + " 被打断!"); } finally { lock.unlock(); } } }; threads.add(thread); thread.start(); } // 会在线程上打上一个interrupt标记 threads.get(3).interrupt(); // 主线程阻塞 LockSupport.park(); } }
输出结果:
线程: 0 开始执行! Exception in thread "线程: 3" java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) 线程: 3 被打断! at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261) at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) at concurrent.reentrantLockDemo.NonFairReentrantLock$1.run(NonFairReentrantLock.java:30) 线程: 0 执行结束! 线程: 1 开始执行! 线程: 1 执行结束! 线程: 2 开始执行! 线程: 2 执行结束! 线程: 4 开始执行! 线程: 4 执行结束! 线程: 5 开始执行! 线程: 5 执行结束! 线程: 6 开始执行! 线程: 6 执行结束! 线程: 7 开始执行! 线程: 7 执行结束! 线程: 8 开始执行! 线程: 8 执行结束! 线程: 9 开始执行! 线程: 9 执行结束!
结合BlockingQueue 案例说明
结合Semaphore案例说明
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。