jdk并发包ReentrantLock 源码导读

1,ReentrantLock实现了Lock接口,下面是Lock接口。定义了一些Lock的基本操作。

jdk并发包ReentrantLock 源码导读
vcv4zczNwsG/sci3x7mrxr3L+NChuty24KGjPC9wPgo8cD40o6xTeW5jzai5/UFic3RyYWN0UXVldWVkU3luY2hyb25pemVyo6hBUVOjqcC0udzA7bbUTG9ja7XEyrnTw6GjQVFTxNqyv82ouf3OrLuk0ru49mxvY2sgcXVldWXAtM6su6S21Mv4tcTV+dPDoaO4xGxvY2sgcXVldWXKx0NMSCBsb2NrcyC1xNK7uPax5NbWoaPPwsPmyse92rXjtcS2qNLlPC9wPgo8cD48cHJlIGNsYXNzPQ=="brush:java;"> static final class Node { /** waitStatus value to indicate thread has cancelled */ static final int CANCELLED = 1; /** waitStatus value to indicate successor's thread needs unparking */ static final int SIGNAL = -1; /** waitStatus value to indicate thread is waiting on condition */ static final int CONDITION = -2; /** Marker to indicate a node is waiting in shared mode */ static final Node SHARED = new Node(); /** Marker to indicate a node is waiting in exclusive mode */ static final Node EXCLUSIVE = null; /** * Status field, taking on only the values: * SIGNAL: The successor of this node is (or will soon be) * blocked (via park), so the current node must * unpark its successor when it releases or * cancels. To avoid races, acquire methods must * first indicate they need a signal, * then retry the atomic acquire, and then, * on failure, block. * CANCELLED: This node is cancelled due to timeout or interrupt. * Nodes never leave this state. In particular, * a thread with cancelled node never again blocks. * CONDITION: This node is currently on a condition queue. * It will not be used as a sync queue node until * transferred. (Use of this value here * has nothing to do with the other uses * of the field, but simplifies mechanics.) * 0: None of the above * * The values are arranged numerically to simplify use. * Non-negative values mean that a node doesn't need to * signal. So, most code doesn't need to check for particular * values, just for sign. * * The field is initialized to 0 for normal sync nodes, and * CONDITION for condition nodes. It is modified only using * CAS. */ volatile int waitStatus; /** * Link to predecessor node that current node/thread relies on * for checking waitStatus. Assigned during enqueing, and nulled * out (for sake of GC) only upon dequeuing. Also, upon * cancellation of a predecessor, we short-circuit while * finding a non-cancelled one, which will always exist * because the head node is never cancelled: A node becomes * head only as a result of successful acquire. A * cancelled thread never succeeds in acquiring, and a thread only * cancels itself, not any other node. */ volatile Node prev; /** * Link to the successor node that the current node/thread * unparks upon release. Assigned once during enqueuing, and * nulled out (for sake of GC) when no longer needed. Upon * cancellation, we cannot adjust this field, but can notice * status and bypass the node if cancelled. The enq operation * does not assign next field of a predecessor until after * attachment, so seeing a null next field does not * necessarily mean that node is at end of queue. However, if * a next field appears to be null, we can scan prev's from * the tail to double-check. */ volatile Node next; /** * The thread that enqueued this node. Initialized on * construction and nulled out after use. */ volatile Thread thread; /** * Link to next node waiting on condition, or the special * value SHARED. Because condition queues are accessed only * when holding in exclusive mode, we just need a simple * linked queue to hold nodes while they are waiting on * conditions. They are then transferred to the queue to * re-acquire. And because conditions can only be exclusive, * we save a field by using special value to indicate shared * mode. */ Node nextWaiter; /** * Returns true if node is waiting in shared mode */ final boolean isShared() { return nextWaiter == SHARED; } /** * Returns previous node, or throws NullPointerException if * null. Use when predecessor cannot be null. * @return the predecessor of this node */ final Node predecessor() throws NullPointerException { Node p = prev; if (p == null) throw new NullPointerException(); else return p; } Node() { // Used to establish initial head or SHARED marker } Node(Thread thread, Node mode) { // Used by addWaiter this.nextWaiter = mode; this.thread = thread; } Node(Thread thread, int waitStatus) { // Used by Condition this.waitStatus = waitStatus; this.thread = thread; } }
5,ReentrantLock中对锁的调用实际调的都是Sync的子类。比如:

public void lock() { sync.lock(); }

6,在中有一个重要的方法如下。通过该方法我们可以获取Condition.通过条件变量Condition,我们更灵活的使用锁。可以实现类似Object.wait/notify/notifyAll的应用场景

public Condition newCondition() { return sync.newCondition(); }

7,下面是condition的例子

package com.j2se.concurrence.lockcondition; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Lock test * * @author joeyon * @date Aug 14, 2014 8:04:57 PM */ public class LockTest { private static int i; private static Lock lk = new ReentrantLock(); public static void test() { List list = new ArrayList(); int tcount = 3; // prepare threads for (int i = 0; i
8,read/write lock例子 :

package com.j2se.concurrence.lockcondition; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Read Write Lock test * * @author joeyon * @date Aug 14, 2014 10:34:08 PM */ public class ReadWriteLockTest { private static int i; private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static Lock rlk = lock.readLock(); private static Lock wlk = lock.writeLock(); private static String data = ""; private static volatile long lastUpdate; // track last publish date /** * publish data, use write lock, * * @param newData */ public static void publish(String newData) { wlk.lock(); try { printTime("begin publish"); data = newData; lastUpdate = System.currentTimeMillis(); // modify last update date printTime("data:\n\t" + data); printTime("end publish"); } catch (Exception e) { e.printStackTrace(); } finally { wlk.unlock(); } } /** * view data, use read lock * * @param previousView * last viewed publish date * @return date of new publish, or -1 if no new publish */ public static long view(long previousView) { if (previousView tViewList = new ArrayList(); final List tLastView = new ArrayList(); // keep track of last viewed publish date for (int i = 0; i 0) { tLastView.set(_index, _lastDate); // update last viewed publish date, if has new publish } try { Thread.sleep(1000 * 4); // view interval } catch (InterruptedException e) { e.printStackTrace(); } } } }, "t-view-" + i)); tLastView.add(0L); } tPublish.start(); for (int i = 0; i
参考:http://kuchaguangjie.iteye.com/blog/1632154
http://www.blogjava.net/xylz/archive/2010/07/15/326152.html
http://www.cnblogs.com/MichaelPeng/archive/2010/02/12/1667947.html
http://flyfoxs.iteye.com/blog/2101244

点击复制链接 与好友分享!回本站首页
您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力
上一篇:从二进制代码来看静态链接本质
下一篇:Spring-SpringMVC-Mybatis整合
相关文章

Java源码:URL编程

Java源码分析:深入探讨Iterator模式

Java 2源码解读:java.util.ArrayList

看JTS源码,感受Java优化编程(一)

由Eclipse源码跳转功能想到的一个Java

LinkedHashMap源码浅析

Java源码解读之util.ArrayList .

Spring ContextLoaderListener源码分析

深入Log4J源码之Log4J Core

Tomcat源码--服务启动

图文推荐
jdk并发包ReentrantLock 源码导读
适配器模式
jdk并发包ReentrantLock 源码导读
Handler的介绍和使用
jdk并发包ReentrantLock 源码导读
struts2上传文件
jdk并发包ReentrantLock 源码导读
通过JFreeChart的饼状

分类:默认分类 时间:2012-11-02 人气:4
本文关键词:
分享到:

相关文章

  • 在JDK 5.0中使用灵活的线程锁定机制 2012-03-26

    JDK 5.0为开发人员开发高性能的并发应用程序提供了一些很有效的新选择。例如,java.util.concurrent.lock 中的类 ReentrantLock 被作为Java 语言中synchronized 功能的替代,它具有相同的内存语义、相同的锁定,但在争用条件下却有更好的性能,此外,它还有synchronized 没有提供的其他特性。这是否意味着我们应当忘记synchronized ,转而只用 ReentrantLock 呢?并发性专家 Brian Goetz 刚从他的夏季休假中返

  • Ubuntu 12.10 安装 JDK 7u15官方版 2012-01-09

    1. 打开官网下载Java安装文件 jdk-7u15-linux-x64.tar.gz 2.打开终端,根据个人习惯建立目录 sudo mkdir /usr/local/development 3.将下载的文件移动到这个文件夹下面并进行解压。使用如下命令: sudo mv jdk-7u15-linux-x64.tar.gz /usr/local/development sudo tar -zxvf jdk-7u15-linux-x64.tar.gz 4.修改环境变量 sudo gedit /etc

  • Linux 下 (RedHat 9.0) JDK,Tomcat,MySQL的安装 2012-02-21

    1 J2SDK的安装 先去java.sun.com上下载Linux上的JDK,我下的是6.0的。 jdk-6u4-linux-i586-rpm.bin ,然后ftp到Linux上, 执行: chmod 755 jdk-6u4-linux-i586-rpm.bin 然后执行 ./jdk-6u4-linux-i586-rpm.bin 就会自动产生并安装一大堆的rpm包,完成后就可以使用java了,JDK5.0以上不需要设置PATH,CLASS_PATH啥的,直接就可以用。 2 TOMCAT 的安装

  • CentOS安装jdk 1.6教程 2012-03-01

    在linux上很多程序都需要jdk的支持,但jdk 1.7对这些程序来说的确太新了,今天就把jdk 1.6安装上去. 系统:centos 5.5 (32位) 需要的软件包:jdk-6u32-linux-i586-rpm.bin 1.下载jdk去官网上下载jdk 1.6 地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u32-downloads-1594644.html 2.安装jdk 1.6 复制代码 代码如下:

  • SDK.JDK.JRE 和JVM 之间的关系 2012-03-12

    SDK(Software Develop Kit,软件开发工具包),用于帮助开发人员的提高工作效率。各种不同类型的软件开发,都可以有自己的SDK。Windows有Windows SDK,DirectX 有 DirectX 9 SDK,.NET开发也有Microsoft .NET Framework SDK。JAVA开发也不含糊,也有自己的Java SDK。   Java SDK最早叫Java Software Develop Kit,后来改名为JDK,即Java Develop Kit。   J

  • Android Studio 0.3使用中JDK版本不兼容解决方案 2012-03-15

    至2013年11月1日,目前Android Studio的版本更新至0.3.2,支持Android 4.4 KitKat. 查看新增功能。 在有些Linux系统上,这版的Studio会运行失败,抛出:“The window must use a translucency-compatible graphics configuration”的错误。 解决办法是将你的JDK更新至JDK 7,JDK不兼容的bug将会在下一版的Android Studio中修复。 另外在windows中也会出现错误!

  • VM下安装JDK的Linux安装版本 2012-04-22

    对于Linux安装JDK,需要进行以下几个步骤: 1、从sun公司网站下载JDK的Linux安装版本:http://www.oracle.com/technetwork/java/javase/downloads/index.html 2、通过ftp将该文件上传到Linux 先确认Linux上已经安装了Vsftpd服务器并且已经启动 在dos下将jdk上传到Linxux 用putty客户端连接远程Linux,查看/var/ftp目录,发现文件已经上传vcD4KPHA+ICAgICAgICA8aW

  • Java学习系列(一)Java的运行机制.JDK的安装配置及常用命令详解 2012-04-30

    俗话说:“十五的月亮十六圆”。那学习是不是也是如此呢?如果把月亮看成是我们的愿望,那十五便是我们所处的“高原期”,坚持迈过这个坎,我相信你的愿望终究会现实的。记得马云曾说:今天很残酷,明天更残酷,后天很美好,但绝大部分人是死在明天晚上,所以每个人不要放弃今天。是的,我们不应该放弃今天,因为每个脚印都值得期待,每一次机会都值得尝试。不扯了,还是步入正题吧! Java的运行机制:Java源程序经过编译器编译成平台无关的字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码发送给特定平台的解释器

  • Android Studio如何更改JDK和SDK的路径? 2012-06-11

    这个对于很多刚转到Android Studio上的来说,确实是一个问题。可能你在设置里面找了很久都没找到这个选项。 直接上图吧,按下图就可以找到设置的地儿了,然后直接设置到你SDK或者JDK的路径即可: vcD4KPHA+PGltZyBzcmM9"http://www.2cto.com/uploadfile/Collfiles/20141026/2014102609430468.jpg" alt="">

Copyright (C) quwantang.com, All Rights Reserved.

趣玩堂 版权所有 京ICP备15002868号

processed in 0.093 (s). 10 q(s)