KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > util > Semaphore


1 /*
2   Based on some code found with Google, somewhere in the Internet
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.util;
19
20 import org.apache.log4j.Logger;
21
22
23
24 /**
25  * This is a simple implementation of the well-known semaphore synchronization feature.
26  *
27  * <p>It allows a given number of thread to be blocked waiting for a
28  * resource to be freed by the threads that are currently using it. */

29
30 public class Semaphore {
31     static Logger logger = Logger.getLogger("semaphore");
32
33     /** The available resources count. */
34     protected int count = 0;
35     private int waitingCount = 0;
36    
37     /**
38      * The semaphore constructor that allows the programmer to assign a
39      * number of resources item that are greater than 0 or 1 (meaning
40      * that several threads (n exactly) can use the semaphore at the
41      * same time).
42      *
43      * @param n the number of resource items */

44
45     public Semaphore(int n) {
46         this.count = n;
47     }
48
49     /**
50      * The default constructor for this semaphore equivalent to
51      * <code>Semaphore(0)</code>.
52      *
53      * <p>This constructor means that no resources are available by
54      * default. Thus, the first thread (t1) that will acquire the
55      * semaphore will eventually by blocked until another thread (t2)
56      * releases a resource on this semaphore.
57      *
58      * <p>This use of the semaphore feature is quite strange regarding
59      * resources (since the deblocking thread (t2) releases a resource
60      * that it never acquired!!) but it can be very usefull for
61      * synchronization especially if t1 waits for a result that is
62      * being calculating by t2 and that is not yet available. */

63
64     public Semaphore() {
65     }
66
67     /**
68      * Gets the number of threads that are currently blocked on this
69      * semaphore.
70      *
71      * <p>This method is an indication but is not safe since a thread
72      * can be released meantime you evaluate its result.
73      *
74      * @return the waiting threads number at the moment you have asked
75      * it */

76
77     public int getWaitingCount() {
78         return waitingCount;
79     }
80
81     public int getCount() {
82         return count;
83     }
84
85     /**
86      * Acquires a resource on this semaphore with no timeout.
87      *
88      * <p>If no resources are available anymore (count == 0), then the
89      * thread that performed this call is blocked until another thread
90      * releases a resource.</p>
91      *
92      * @return true if the resource could be aquired.
93      *
94      * @see #acquire(long)
95      * @see #release()
96      */

97     public boolean acquire() {
98         return acquire(0);
99     }
100
101     /**
102      * Acquires a resource on this semaphore.
103      *
104      * <p>If no resources are available anymore (count == 0), then the
105      * thread that performed this call is blocked until another thread
106      * releases a resource.
107      *
108      * @param timeout milliseconds to wait for. 0 means wait for ever.
109      * @return true if the resource could be aquired.
110      *
111      * @see #acquire()
112      * @see #release()
113      */

114     public synchronized boolean acquire(long timeout) {
115         waitingCount++;
116         while(count == 0) {
117             logger.debug(this+" acquire, waiting; count = "+count);
118             try {
119                 wait(timeout);
120                 // I think this is not correct in the general case but
121
// should work if there's only on thread waiting.
122
if (count==0)
123                     return false;
124             } catch (InterruptedException JavaDoc e) {
125                 //keep trying
126
}
127         }
128         logger.debug(this+" acquired, count = "+count+"(--)");
129         count--;
130         waitingCount--;
131         return true;
132     }
133
134     /**
135      * Releases a resource on this semaphore.
136      *
137      * <p>If one or several threads are blocked, waiting for a resource
138      * to be available, then this call will necessaraly makes one of
139      * them take the semaphore's monitor (the others, if any will block
140      * again). There is absolutly no way of knowing which thread will
141      * take the monitor first.
142      *
143      * @see #acquire()
144      */

145     public synchronized void release() {
146         logger.debug(this+" release, count = "+count+"(++)");
147         count++;
148         notify(); //alert a thread that's blocking on this semaphore
149
}
150 }
151
Popular Tags