Jdk package ReentrantLock source code Introduction

Source: Internet
Author: User
Tags read write lock

Jdk package ReentrantLock source code Introduction

1. ReentrantLock implements the Lock interface. below is the Lock interface. Defines some basic Lock operations.

Vcv4zczNwsG/sci3x7mrxr3L + NChuty24KGjPC9wPgo8cD40o6xTeW5jzai5/placement + placement = "brush: java; "> static final class Node {/** waitStatus value to indicate thread has canceled */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 canceled due to timeout or interrupt. * Nodes never leave this state. in particle, * a thread with canceled 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 mechanic .) * 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 special * 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-canceled one, which will always exist * because the head node is never canceled: A node becomes * head only as a result of successful acquire. A * canceled 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 canceled. 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. The actual calls to locks in ReentrantLock are subclasses of Sync. For example:

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

6. An important method is as follows. Through this method, we can obtain the Condition. By using the conditional variable Condition, we can use the lock more flexibly. It can implement application scenarios similar to Object. wait/policy/policyall.

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

7. The following example shows 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 threadsfor (int i = 0; i < tcount; i++) {list.add(new Thread(new TmpRunnable(), "t-" + i));}// start threadsfor (int i = 0; i < tcount; i++) {list.get(i).start();}}private static class TmpRunnable implements Runnable {@Overridepublic void run() {lk.lock();try {printTime("begin");Thread.sleep(1000 * 1); // sleep a while, for test purposeprintTime("end");} catch (InterruptedException e) {e.printStackTrace();} finally {lk.unlock();}}}public static void printTime() {printTime("");}/** * print thread name & time *  * @param info *            additional info to print */public synchronized static void printTime(String info) {System.out.printf("%s:\t%d,\t,%d,\t%s\n", Thread.currentThread().getName(), ++i, System.currentTimeMillis() / 1000, info);}public static void main(String[] args) {test();}}
  
 

8. read/write lock example:

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 dateprintTime("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 < lastUpdate) { // new publishrlk.lock();try {printTime("view data:\n\t" + data);} catch (Exception e) {e.printStackTrace();} finally {rlk.unlock();}return lastUpdate;} else { // no new publishprintTime("no new publish yet");return -1;}}public static void test() throws InterruptedException {Thread tPublish = new Thread(new Runnable() {@Overridepublic void run() {while (true) {publish("hi, xxxxxx, data_" + i + "_xxxxxx");try {Thread.sleep(1000 * 10); // update interval} catch (InterruptedException e) {e.printStackTrace();}}}}, "t-publish");// prepare view threadsint tViewCount = 3; // count of view threadList
 
   tViewList = new ArrayList
  
   ();final List
   
     tLastView = new ArrayList
    
     (); // keep track of last viewed publish datefor (int i = 0; i < tViewCount; i++) {final int _index = i;tViewList.add(new Thread(new Runnable() {@Overridepublic void run() {while (true) {long _lastDate = view(tLastView.get(_index));if (_lastDate > 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 < tViewCount; i++) {tViewList.get(i).start();Thread.sleep(1000 * 5); // start interval of view threads}}public static void printTime() {printTime("");}/** * print thread name & time *  * @param info *            additional info to print */public synchronized static void printTime(String info) {System.out.printf("%s:\t%d,\t,%d,\t%s\n", Thread.currentThread().getName(), ++i, System.currentTimeMillis() / 1000, info);}public static void main(String[] args) throws InterruptedException {test();}}
    
   
  
 

Reference: 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







Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.