KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > quartz > impl > jdbcjobstore > SimpleSemaphore


1 /*
2  * Copyright 2004-2005 OpenSymphony
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy
6  * of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations
14  * under the License.
15  *
16  */

17
18 /*
19  * Previously Copyright (c) 2001-2004 James House
20  */

21 package org.quartz.impl.jdbcjobstore;
22
23 import java.sql.Connection JavaDoc;
24 import java.util.HashSet JavaDoc;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * Internal in-memory lock handler for providing thread/resource locking in
31  * order to protect resources from being altered by multiple threads at the
32  * same time.
33  *
34  * @author jhouse
35  */

36 public class SimpleSemaphore implements Semaphore {
37
38     /*
39      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40      *
41      * Data members.
42      *
43      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44      */

45
46     ThreadLocal JavaDoc lockOwners = new ThreadLocal JavaDoc();
47
48     HashSet JavaDoc locks = new HashSet JavaDoc();
49
50     private final Log log = LogFactory.getLog(getClass());
51
52     /*
53      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
54      *
55      * Interface.
56      *
57      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58      */

59
60     protected Log getLog() {
61         return log;
62     }
63
64     private HashSet JavaDoc getThreadLocks() {
65         HashSet JavaDoc threadLocks = (HashSet JavaDoc) lockOwners.get();
66         if (threadLocks == null) {
67             threadLocks = new HashSet JavaDoc();
68             lockOwners.set(threadLocks);
69         }
70         return threadLocks;
71     }
72
73     /**
74      * Grants a lock on the identified resource to the calling thread (blocking
75      * until it is available).
76      *
77      * @return true if the lock was obtained.
78      */

79     public synchronized boolean obtainLock(Connection JavaDoc conn, String JavaDoc lockName) {
80
81         lockName = lockName.intern();
82
83         Log log = getLog();
84
85         if(log.isDebugEnabled()) {
86             log.debug(
87                 "Lock '" + lockName + "' is desired by: "
88                         + Thread.currentThread().getName());
89         }
90
91         if (!isLockOwner(conn, lockName)) {
92             if(log.isDebugEnabled()) {
93                 log.debug(
94                     "Lock '" + lockName + "' is being obtained: "
95                             + Thread.currentThread().getName());
96             }
97             while (locks.contains(lockName)) {
98                 try {
99                     this.wait();
100                 } catch (InterruptedException JavaDoc ie) {
101                     if(log.isDebugEnabled()) {
102                         log.debug(
103                             "Lock '" + lockName + "' was not obtained by: "
104                                     + Thread.currentThread().getName());
105                     }
106                 }
107             }
108
109             if(log.isDebugEnabled()) {
110                 log.debug(
111                     "Lock '" + lockName + "' given to: "
112                             + Thread.currentThread().getName());
113             }
114             getThreadLocks().add(lockName);
115             locks.add(lockName);
116         } else if(log.isDebugEnabled()) {
117             log.debug(
118                 "Lock '" + lockName + "' already owned by: "
119                         + Thread.currentThread().getName()
120                         + " -- but not owner!",
121                 new Exception JavaDoc("stack-trace of wrongful returner"));
122         }
123
124         return true;
125     }
126
127     /**
128      * Release the lock on the identified resource if it is held by the calling
129      * thread.
130      */

131     public synchronized void releaseLock(Connection JavaDoc conn, String JavaDoc lockName) {
132
133         lockName = lockName.intern();
134
135         if (isLockOwner(conn, lockName)) {
136             if(getLog().isDebugEnabled()) {
137                 getLog().debug(
138                     "Lock '" + lockName + "' retuned by: "
139                             + Thread.currentThread().getName());
140             }
141             getThreadLocks().remove(lockName);
142             locks.remove(lockName);
143             this.notify();
144         } else if (getLog().isDebugEnabled()) {
145             getLog().debug(
146                 "Lock '" + lockName + "' attempt to retun by: "
147                         + Thread.currentThread().getName()
148                         + " -- but not owner!",
149                 new Exception JavaDoc("stack-trace of wrongful returner"));
150         }
151     }
152
153     /**
154      * Determine whether the calling thread owns a lock on the identified
155      * resource.
156      */

157     public synchronized boolean isLockOwner(Connection JavaDoc conn, String JavaDoc lockName) {
158
159         lockName = lockName.intern();
160
161         return getThreadLocks().contains(lockName);
162     }
163
164     /**
165      * This Semaphore implementation does not use the database.
166      */

167     public boolean requiresConnection() {
168         return false;
169     }
170 }
171
Popular Tags