View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.orchestra.lib;
20  
21  
22  /**
23   * A reentrant mutual exclusion with the same basic
24   * behavior and semantics as the implicit monitor lock accessed using
25   * {@code synchronized} methods and statements.
26   * <p>
27   * Serialization of this class behaves in the same way as built-in
28   * locks: a deserialized lock is in the unlocked state, regardless of
29   * its state when serialized.
30   * <p>
31   * This class exists just for the purposes of Java 1.4 compatibility;
32   * it is equivalent to the Java 1.5 ReentrantLock class. It probably
33   * doesn't perform as well as the "real" lock class, but Orchestra
34   * doesn't use it in any critical paths.
35   * 
36   * @since 1.1
37   */
38  public class _ReentrantLock implements java.io.Serializable {
39      private static final long serialVersionUID = 7373984872572414699L;
40  
41      private transient Thread lockedBy;
42      private int lockCount;
43      
44      public void lockInterruptibly() throws InterruptedException
45      {
46          Thread caller = Thread.currentThread();
47          for(;;)
48          {
49              synchronized(this)
50              {
51                  if (lockedBy == null)
52                  {
53                      lockedBy = caller;
54                      lockCount = 1;
55                      return;
56                  } 
57      
58                  if (lockedBy == caller)
59                  {
60                      ++lockCount;
61                      return;
62                  }
63      
64                  try
65                  {
66                      this.wait();
67                  }
68                  catch(InterruptedException e)
69                  {
70                      throw e;
71                  }
72              }
73          }
74      }
75      
76      public void unlock()
77      {
78          Thread caller = Thread.currentThread();
79          synchronized(this)
80          {
81              if (lockedBy != caller)
82              {
83                  throw new IllegalStateException("Unlock on lock not owned by caller");
84              }
85              
86              --lockCount;
87              if (lockCount == 0)
88              {
89                  lockedBy = null;
90                  this.notifyAll();
91              }
92          }
93      }
94      
95      public boolean isHeldByCurrentThread()
96      {
97          Thread caller = Thread.currentThread();
98          synchronized(this)
99          {
100             return lockedBy == caller;
101         }
102     }
103 }