- 浏览: 742662 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 15662jetty版本:jetty-6.1.26 1.由于jetty ... -
线程池--jetty中QueuedThreadPool分析(一)
2012-02-02 10:48 0d -
java并发编程--ThreadLocal的用法和分析
2012-01-11 22:55 17675ThreadLocal这个类,理解起来比较简单,但是使用时, ... -
java并发编程--Semaphore信号量分析(七)
2012-01-08 22:25 0Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把 ... -
java并发编程--AbstractQueuedSynchronizer的tryLock()方法分析(六)
2012-01-05 14:40 2322tryLock()仅尝试一次获取锁,不管成功与否,都将返回结 ... -
java并发编程--AbstractQueuedSynchronizer条件锁分析(四)
2011-12-30 17:10 2268前一篇J.U.C的 ... -
java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)
2011-12-30 14:40 3926juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非 ... -
java并发编程--AbstractQueuedSynchronizer加锁和解锁分析(二)
2011-12-29 22:07 8587在java.util.concurrent.locks ... -
JAXB--@XmlType注解标注xml生成顺序(四)
2011-11-03 17:01 34427默认情况下,Jaxb编组出来的xml中的字段顺序是随机的,你可 ... -
JAXB--@XmlElementWrapper注解和泛型一起使用(三)
2011-11-03 16:46 20753当java对象的某个属性使 ... -
JAXB--@XmlElementWrapper注解(二)
2011-11-03 15:49 32489在JAXB标准中,@XmlElementWrapper注解表示 ... -
JAXB--简单应用(一)
2011-11-03 15:09 50459一、简介 1、概念是什么:(Java Archite ... -
Java线程:新特征-锁
2011-10-28 17:39 0在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的 ... -
java线程常见的几种死锁模式和解决方法
2011-10-18 23:09 2216待续 -
利用object.wait()和实现生产者和消费者模式
2011-10-18 23:08 2598其实生产者和消费者模式概念很简单,就是生产者将生产出来 ... -
java线程的同步互斥和通讯
2011-10-18 23:01 3646一、同步和锁定 1、锁的原理 Ja ... -
HtmlParser学习笔记(四)-- 使用Filter过滤结点
2010-01-12 12:48 11253使用TagNameFilter过滤所有table标签结 ... -
HtmlParser学习笔记(三)-- 使用Visitor访问结点
2010-01-12 12:48 5440使用NodeVisitor方式访问html结点,代码如 ... -
HtmlParser学习笔记(二)-- 遍历结点
2010-01-12 12:47 4366这次主要演示下,如何迭代一个Node结点的所有根子结点。 ...
相关推荐
62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java并发编程实战62-Java...
CountDownLatch、CyclicBarrier 和 Semaphore 等多线程协作机制都是 Java 并发编程中的重要组成部分。它们可以帮助开发者编写高效、可靠的多线程程序,解决复杂的并发问题。 在实际开发中,我们可以根据具体情况...
Java并发编程-设计原则与模式 pdf格式
Java并发编程实践-电子书-01章.pdf Java并发编程实践-电子书-02章.pdf Java并发编程实践-电子书-03章.pdf Java并发编程实践-电子书-04章.pdf Java并发编程实践-电子书-05章.pdf Java并发编程实践-电子书-06章.pdf ...
Java提供了丰富的并发工具和API来支持并发编程,如线程(Thread)、Executor框架、Future、Callable和Runnable接口等。 在Java中,线程的创建和管理是通过继承Thread类或实现Runnable接口来完成的。理解如何正确地...
### Java并发编程-AQS和JUC实战 #### 一、ReentrantLock 重入锁 **1.1 概述** - **基本介绍**: `ReentrantLock` 是一个实现了 `Lock` 接口的可重入互斥锁,提供比 `synchronized` 更丰富的功能。与 `synchronized...
阿里专家级并发编程架构师级课程,完成课程的学习可以帮助同学们解决非常多的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中用于构建高效并发应用的核心工具和概念。 1. **线程**:Java中的线程是并发编程的基础,每个...
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...
【Java 并发编程-超级大全整理】 Java 并发编程是Java开发中不可或缺的一部分,尤其是在高并发场景下,能够有效提升程序的运行效率。本文将深入探讨Java多线程的相关知识点,帮助开发者理解并掌握如何在Java环境中...
《Java并发编程实战》这本书是关于Java语言中并发编程技术的经典著作。它详细介绍了如何在Java环境中有效地实现多线程程序和并发控制机制。在Java平台上,由于其本身提供了强大的并发编程支持,因此,掌握并发编程...
在Java编程领域,多线程并发是不可或缺的一部分,特别是在服务器端和高并发应用中。本文将深入探讨"Java并发编程-线程安全与基础构建模块"这一主题,旨在帮助开发者理解如何有效地处理并发问题,提高程序性能和稳定...
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。阿里大牛梁飞编写的《Java并发编程常识》PPT,深入浅出地讲解了这个主题,对开发者来...
《Java并发编程实战》是一本深入探讨Java平台并发编程的权威指南。这本书旨在帮助开发者理解和掌握在Java环境中创建高效、可扩展且可靠的多线程应用程序的关键技术和实践。它涵盖了从基本概念到高级主题的广泛内容,...
《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...
Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。这份“java并发编程内部分享PPT”显然是一个深入探讨这一主题的资料,旨在帮助开发者...
总而言之,《Java并发编程艺术》这本书将系统性地介绍Java并发编程的各种技术和最佳实践,帮助读者提升在多线程环境下的编程能力,从而设计出更加健壮、高效的Java应用。无论你是初级开发者还是经验丰富的工程师,这...