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  
20  
21  
22  package org.apache.james.util;
23  
24  import java.util.Hashtable;
25  
26  /**
27   * Provides Lock functionality
28   *
29   */
30  public class Lock {
31      /**
32       * An internal hash table of keys to locks
33       */
34      private Hashtable locks = new Hashtable();
35  
36      /**
37       * Check to see if the object is locked
38       *
39       * @param key the Object on which to check the lock
40       * @return true if the object is locked, false otherwise
41       */
42      public boolean isLocked(final Object key) {
43          return (locks.get(key) != null);
44      }
45  
46      /**
47       * Check to see if we can lock on a given object.
48       *
49       * @param key the Object on which to lock
50       * @return true if the calling thread can lock, false otherwise
51       */
52      public boolean canI(final Object key) {
53          Object o = locks.get( key );
54  
55          if (null == o || o == this.getCallerId()) {
56              return true;
57          }
58  
59          return false;
60      }
61  
62      /**
63       * Lock on a given object.
64       *
65       * @param key the Object on which to lock
66       * @return true if the locking was successful, false otherwise
67       */
68      public boolean lock(final Object key) {
69          Object theLock;
70  
71          synchronized(this) {
72              theLock = locks.get(key);
73  
74              if (null == theLock) {
75                  locks.put(key, getCallerId());
76                  return true;
77              } else if (getCallerId() == theLock) {
78                  return true;
79              } else {
80                  return false;
81              }
82          }
83      }
84  
85      /**
86       * Release the lock on a given object.
87       *
88       * @param key the Object on which the lock is held
89       * @return true if the unlocking was successful, false otherwise
90       */
91      public boolean unlock(final Object key) {
92          Object theLock;
93          synchronized (this) {
94              theLock = locks.get(key);
95  
96              if (null == theLock) {
97                  return true;
98              } else if (getCallerId() == theLock) {
99                  locks.remove(key);
100                 return true;
101             } else {
102                 return false;
103             }
104         }
105     }
106 
107     /**
108      * Private helper method to abstract away caller ID.
109      *
110      * @return the id of the caller (i.e. the Thread reference)
111      */
112     private Object getCallerId() {
113         return Thread.currentThread();
114     }
115 }