- 浏览: 738348 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
nmgrd:
赞一个,在分析AQS源码的博客当中,楼主是写的最细致,最易懂, ...
java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三) -
ljzxloaf:
阻塞和等待不一样吧,condition持有等待队列,而AQS持 ...
java并发编程--AbstractQueuedSynchronizer加锁和解锁分析(二) -
DaCang4535:
楼主,不知道你那个book类有什么作用。setBook那个方法 ...
JAXB--简单应用(一) -
yuhui0531:
f-u-c-k!!!!!!!!!!!!!!!!!!!!!!!! ...
java线程常见的几种死锁模式和解决方法 -
刘文超:
form提交的几种方法
java并发编程--AbstractQueuedSynchronizer的lock()和lockInterruptibly()方法分析(五)
- 博客分类:
- Java高级
lock 与 lockInterruptibly比较区别在于:
lock 优先考虑获取锁,待获取锁成功后,才响应中断。
lockInterruptibly 优先考虑响应中断,而不是响应锁的普通获取或重入获取。
详细区别:
ReentrantLock.lockInterruptibly允许在等待时由其它线程调用等待线程的Thread.interrupt方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个InterruptedException。 ReentrantLock.lock方法不允许Thread.interrupt中断,即使检测到Thread.isInterrupted,一样会继续尝试获取锁,失败则继续休眠。只是在最后获取锁成功后再把当前线程置为interrupted状态,然后再中断线程。
那lockInterruptibly是如何做到这一点的?
public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); }
这里调用了AbstractQueuedSynchronizer.acquireInterruptibly方法。如果线程已被中断则直接抛出异常,否则则尝试获取锁,失败则doAcquireInterruptibly()
AbstractQueuedSynchronizer.acquireInterruptibly(int arg)
/** * Acquires in exclusive mode, aborting if interrupted. * Implemented by first checking interrupt status, then invoking * at least once {@link #tryAcquire}, returning on * success. Otherwise the thread is queued, possibly repeatedly * blocking and unblocking, invoking {@link #tryAcquire} * until success or the thread is interrupted. This method can be * used to implement method {@link Lock#lockInterruptibly}. * * @param arg the acquire argument. This value is conveyed to * {@link #tryAcquire} but is otherwise uninterpreted and * can represent anything you like. * @throws InterruptedException if the current thread is interrupted */ public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); }
AbstractQueuedSynchronizer.doAcquireInterruptibly大体上相当于前面的acquireQueued,关键的区别在于检测到interrupted后的处理,acquireQueued简单的记录下中断曾经发生,然后就象没事人似的去尝试获取锁,失败则休眠。而doAcquireInterruptibly检测到中断则直接退出循环,抛出InterruptedException异常。
AbstractQueuedSynchronizer.doAcquireInterruptibly(int arg)
/** * Acquires in exclusive interruptible mode. * @param arg the acquire argument */ private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); try { for (;;) { final Node p = node.predecessor(); /* acquireQueued代码: if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; */ if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) break; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted // 取消获取锁尝试,将当前节点从等待队列中移除 cancelAcquire(node); throw new InterruptedException(); }
在抛出异常之前,doAcquireInterruptibly还做了一件事情,cancelAcquire。cancelAcquire中有些细节值得玩味,参见代码中笔者注释。
AbstractQueuedSynchronizer.cancelAcquire(Node node)
/** * Cancels an ongoing attempt to acquire. * * @param node the node */ private void cancelAcquire(Node node) { // Ignore if node doesn"t exist if (node == null) return; node.thread = null; // Skip cancelled predecessors // 头节点一定不会是在等待状态,所以不会被cancel,所以这里一定能找到一个节点而不用担心null Node pred = node.prev; while (pred.waitStatus > 0) node.prev = pred = pred.prev; // Getting this before setting waitStatus ensures staleness Node predNext = pred.next; // Can use unconditional write instead of CAS here node.waitStatus = Node.CANCELLED; // If we are the tail, remove ourselves if (node == tail && compareAndSetTail(node, pred)) { compareAndSetNext(pred, predNext, null); } else { // If "active" predecessor found... if (pred != head && (pred.waitStatus == Node.SIGNAL || compareAndSetWaitStatus( pred, 0, Node.SIGNAL)) && pred.thread != null) { // If successor is active, set predecessor"s next link Node next = node.next; if (next != null && next.waitStatus <= 0) compareAndSetNext(pred, predNext, next); } else { /*这里如果不调用unparkSuccessor, 若在interrupted之后,执行到上面一句将waitStatus置CANCELLED之前,锁被释放,该线程被唤醒,则释放锁线程的unparkSuccessor不能起到预期作用,所以这里需要调用unparkSuccessor.即使此时持有锁的线程没有释放锁也不会有严重后果,被unpark的线程在获取锁失败后会继续park*/ unparkSuccessor(node); } node.next = node; // help GC } }
发表评论
-
thread方法分析
2012-02-02 13:36 0t.join();表示当前线程停止执行直到t线程运行完毕 ... -
线程池--jetty中QueuedThreadPool分析(一)
2012-02-02 11:09 15534jetty版本:jetty-6.1.26 1.由于jetty ... -
线程池--jetty中QueuedThreadPool分析(一)
2012-02-02 10:48 0d -
java并发编程--ThreadLocal的用法和分析
2012-01-11 22:55 17571ThreadLocal这个类,理解起来比较简单,但是使用时, ... -
java并发编程--Semaphore信号量分析(七)
2012-01-08 22:25 0Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把 ... -
java并发编程--AbstractQueuedSynchronizer的tryLock()方法分析(六)
2012-01-05 14:40 2277tryLock()仅尝试一次获取锁,不管成功与否,都将返回结 ... -
java并发编程--AbstractQueuedSynchronizer条件锁分析(四)
2011-12-30 17:10 2218前一篇J.U.C的 ... -
java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)
2011-12-30 14:40 3866juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非 ... -
java并发编程--AbstractQueuedSynchronizer加锁和解锁分析(二)
2011-12-29 22:07 8500在java.util.concurrent.locks ... -
JAXB--@XmlType注解标注xml生成顺序(四)
2011-11-03 17:01 34365默认情况下,Jaxb编组出来的xml中的字段顺序是随机的,你可 ... -
JAXB--@XmlElementWrapper注解和泛型一起使用(三)
2011-11-03 16:46 20695当java对象的某个属性使 ... -
JAXB--@XmlElementWrapper注解(二)
2011-11-03 15:49 32357在JAXB标准中,@XmlElementWrapper注解表示 ... -
JAXB--简单应用(一)
2011-11-03 15:09 50397一、简介 1、概念是什么:(Java Archite ... -
Java线程:新特征-锁
2011-10-28 17:39 0在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的 ... -
java线程常见的几种死锁模式和解决方法
2011-10-18 23:09 2161待续 -
利用object.wait()和实现生产者和消费者模式
2011-10-18 23:08 2557其实生产者和消费者模式概念很简单,就是生产者将生产出来 ... -
java线程的同步互斥和通讯
2011-10-18 23:01 3602一、同步和锁定 1、锁的原理 Ja ... -
HtmlParser学习笔记(四)-- 使用Filter过滤结点
2010-01-12 12:48 11209使用TagNameFilter过滤所有table标签结 ... -
HtmlParser学习笔记(三)-- 使用Visitor访问结点
2010-01-12 12:48 5411使用NodeVisitor方式访问html结点,代码如 ... -
HtmlParser学习笔记(二)-- 遍历结点
2010-01-12 12:47 4331这次主要演示下,如何迭代一个Node结点的所有根子结点。 ...
相关推荐
62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java...
Java并发编程---synchronized关键
Java并发编程---Thread类!!
B站楠哥JUC Java并发编程
Java并发编程-设计原则与模式 pdf格式
Java并发编程-并发编程知识点总结.docx
Java并发编程实践-电子书-01章.pdf Java并发编程实践-电子书-02章.pdf Java并发编程实践-电子书-03章.pdf Java并发编程实践-电子书-04章.pdf Java并发编程实践-电子书-05章.pdf Java并发编程实践-电子书-06章.pdf ...
java并发编程-超级大全整理
阿里专家级并发编程架构师级课程,完成课程的学习可以帮助同学们解决非常多的JAVA并发编程疑难杂症,极大的提高JAVA并发编程的效率。课程内容包括了JAVA手写线程池,UC线程池API详解,线程安全根因详解,锁与原子类...
07-JUC高并发编程-Lock接口概述和实现案例.mp48 G J/ u; W' _$ o: {2 M 08-JUC高并发编程-线程间通信-概述和案例分析.mp4 09-JUC高并发编程-线程间通信-Synchronized实现案例.mp4 10-JUC高并发编程-线程间通信-虚假...
Java并发编程原汁原味英文版,Doug Lea大神经典著作, 内容:Concurrency Models, design forces, Java Designing objects for concurrency Immutability, locking, state dependence, containment, splitting ...
java并发编程-从入门到精通,相当不错的文档,可以看看,高清
JAVA并发编程实践-中文-高清-带书签-完整版(Doug+Lea)JAVA并发编程实践-中文-高清-带书签-完整版(Doug+Lea)
java并发编程pdf文档第二部分:Java并发编程实战.pdf、Java多线程编程核心技术.pdf、实战Java高并发程序设计.pdf
Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;Java并发编程系列- volatile;
java并发编程实战源码 附有本书所有源码,maven 导入 eclipse或idea
java并发编程艺术java并发编程艺术java并发编程艺术java并发编程艺术java并发编程艺术
JAVA并发编程实践中文版 英文版 原书源码 带书签 java_concurrency_in_practice.pdf 英文版还是不错的,但是中文版的译者典型的没有技术功底,介绍上说什么专家, 翻译的非常差劲,有些句子都不通顺,都不知道自己去...
JAVA并发编程艺术 高清pdf : 1.并发变成的挑战 2. java并发机制的底层实现原理 3. java 内存模型 4. java并发编程基础 5.java中的锁。。。。。。。
Java并发编程系列- synchronized;Java并发编程系列- synchronized;Java并发编程系列- synchronized;