File: ReentrantLock.java

package info (click to toggle)
concurrent-dfsg 1.3.4-4
  • links: PTS, VCS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd, squeeze, stretch, wheezy
  • size: 976 kB
  • ctags: 2,018
  • sloc: java: 10,704; xml: 49; makefile: 12
file content (147 lines) | stat: -rw-r--r-- 3,722 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
  File: ReentrantLock.java

  Originally written by Doug Lea and released into the public domain.
  This may be used for any purposes whatsoever without acknowledgment.
  Thanks for the assistance and support of Sun Microsystems Labs,
  and everyone contributing, testing, and using this code.

  History:
  Date       Who                What
  11Jun1998  dl               Create public version
   5Aug1998  dl               replaced int counters with longs
*/

package EDU.oswego.cs.dl.util.concurrent;

/**
 * A lock with the same semantics as builtin
 * Java synchronized locks: Once a thread has a lock, it
 * can re-obtain it any number of times without blocking.
 * The lock is made available to other threads when
 * as many releases as acquires have occurred.
 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
**/


public class ReentrantLock implements Sync  {

  protected Thread owner_ = null;
  protected long holds_ = 0;

  public void acquire() throws InterruptedException {
    if (Thread.interrupted()) throw new InterruptedException();
    Thread caller = Thread.currentThread();
    synchronized(this) {
      if (caller == owner_) 
        ++holds_;
      else {
        try {  
          while (owner_ != null) wait(); 
          owner_ = caller;
          holds_ = 1;
        }
        catch (InterruptedException ex) {
          notify();
          throw ex;
        }
      }
    }
  }  


  public boolean attempt(long msecs) throws InterruptedException {
    if (Thread.interrupted()) throw new InterruptedException();
    Thread caller = Thread.currentThread();
    synchronized(this) {
      if (caller == owner_) {
        ++holds_;
        return true;
      }
      else if (owner_ == null) {
        owner_ = caller;
        holds_ = 1;
        return true;
      }
      else if (msecs <= 0)
        return false;
      else {
        long waitTime = msecs;
        long start = System.currentTimeMillis();
        try {
          for (;;) {
            wait(waitTime); 
            if (caller == owner_) {
              ++holds_;
              return true;
            }
            else if (owner_ == null) {
              owner_ = caller;
              holds_ = 1;
              return true;
            }
            else {
              waitTime = msecs - (System.currentTimeMillis() - start);
              if (waitTime <= 0) 
                return false;
            }
          }
        }
        catch (InterruptedException ex) {
          notify();
          throw ex;
        }
      }
    }
  }  

  /**
   * Release the lock.
   * @exception Error thrown if not current owner of lock
   **/
  public synchronized void release()  {
    if (Thread.currentThread() != owner_)
      throw new Error("Illegal Lock usage"); 

    if (--holds_ == 0) {
      owner_ = null;
      notify(); 
    }
  }

  /** 
   * Release the lock N times. <code>release(n)</code> is
   * equivalent in effect to:
   * <pre>
   *   for (int i = 0; i < n; ++i) release();
   * </pre>
   * <p>
   * @exception Error thrown if not current owner of lock
   * or has fewer than N holds on the lock
   **/
  public synchronized void release(long n) {
    if (Thread.currentThread() != owner_ || n > holds_)
      throw new Error("Illegal Lock usage"); 

    holds_ -= n;
    if (holds_ == 0) {
      owner_ = null;
      notify(); 
    }
  }


  /**
   * Return the number of unreleased acquires performed
   * by the current thread.
   * Returns zero if current thread does not hold lock.
   **/
  public synchronized long holds() {
    if (Thread.currentThread() != owner_) return 0;
    return holds_;
  }

    

}