76eda01098f1462a429f20580a5f1f2158b5dd32
[IRC.git] / Robust / src / ClassLibrary / MGC / gnu / Semaphore.java
1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/licenses/publicdomain
5  */
6
7 /*package java.util.concurrent;
8 import java.util.*;
9 import java.util.concurrent.locks.*;
10 import java.util.concurrent.atomic.*;*/
11
12 /**
13  * A counting semaphore.  Conceptually, a semaphore maintains a set of
14  * permits.  Each {@link #acquire} blocks if necessary until a permit is
15  * available, and then takes it.  Each {@link #release} adds a permit,
16  * potentially releasing a blocking acquirer.
17  * However, no actual permit objects are used; the {@code Semaphore} just
18  * keeps a count of the number available and acts accordingly.
19  *
20  * <p>Semaphores are often used to restrict the number of threads than can
21  * access some (physical or logical) resource. For example, here is
22  * a class that uses a semaphore to control access to a pool of items:
23  * <pre>
24  * class Pool {
25  *   private static final int MAX_AVAILABLE = 100;
26  *   private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
27  *
28  *   public Object getItem() throws InterruptedException {
29  *     available.acquire();
30  *     return getNextAvailableItem();
31  *   }
32  *
33  *   public void putItem(Object x) {
34  *     if (markAsUnused(x))
35  *       available.release();
36  *   }
37  *
38  *   // Not a particularly efficient data structure; just for demo
39  *
40  *   protected Object[] items = ... whatever kinds of items being managed
41  *   protected boolean[] used = new boolean[MAX_AVAILABLE];
42  *
43  *   protected synchronized Object getNextAvailableItem() {
44  *     for (int i = 0; i < MAX_AVAILABLE; ++i) {
45  *       if (!used[i]) {
46  *          used[i] = true;
47  *          return items[i];
48  *       }
49  *     }
50  *     return null; // not reached
51  *   }
52  *
53  *   protected synchronized boolean markAsUnused(Object item) {
54  *     for (int i = 0; i < MAX_AVAILABLE; ++i) {
55  *       if (item == items[i]) {
56  *          if (used[i]) {
57  *            used[i] = false;
58  *            return true;
59  *          } else
60  *            return false;
61  *       }
62  *     }
63  *     return false;
64  *   }
65  *
66  * }
67  * </pre>
68  *
69  * <p>Before obtaining an item each thread must acquire a permit from
70  * the semaphore, guaranteeing that an item is available for use. When
71  * the thread has finished with the item it is returned back to the
72  * pool and a permit is returned to the semaphore, allowing another
73  * thread to acquire that item.  Note that no synchronization lock is
74  * held when {@link #acquire} is called as that would prevent an item
75  * from being returned to the pool.  The semaphore encapsulates the
76  * synchronization needed to restrict access to the pool, separately
77  * from any synchronization needed to maintain the consistency of the
78  * pool itself.
79  *
80  * <p>A semaphore initialized to one, and which is used such that it
81  * only has at most one permit available, can serve as a mutual
82  * exclusion lock.  This is more commonly known as a <em>binary
83  * semaphore</em>, because it only has two states: one permit
84  * available, or zero permits available.  When used in this way, the
85  * binary semaphore has the property (unlike many {@link Lock}
86  * implementations), that the &quot;lock&quot; can be released by a
87  * thread other than the owner (as semaphores have no notion of
88  * ownership).  This can be useful in some specialized contexts, such
89  * as deadlock recovery.
90  *
91  * <p> The constructor for this class optionally accepts a
92  * <em>fairness</em> parameter. When set false, this class makes no
93  * guarantees about the order in which threads acquire permits. In
94  * particular, <em>barging</em> is permitted, that is, a thread
95  * invoking {@link #acquire} can be allocated a permit ahead of a
96  * thread that has been waiting - logically the new thread places itself at
97  * the head of the queue of waiting threads. When fairness is set true, the
98  * semaphore guarantees that threads invoking any of the {@link
99  * #acquire() acquire} methods are selected to obtain permits in the order in
100  * which their invocation of those methods was processed
101  * (first-in-first-out; FIFO). Note that FIFO ordering necessarily
102  * applies to specific internal points of execution within these
103  * methods.  So, it is possible for one thread to invoke
104  * {@code acquire} before another, but reach the ordering point after
105  * the other, and similarly upon return from the method.
106  * Also note that the untimed {@link #tryAcquire() tryAcquire} methods do not
107  * honor the fairness setting, but will take any permits that are
108  * available.
109  *
110  * <p>Generally, semaphores used to control resource access should be
111  * initialized as fair, to ensure that no thread is starved out from
112  * accessing a resource. When using semaphores for other kinds of
113  * synchronization control, the throughput advantages of non-fair
114  * ordering often outweigh fairness considerations.
115  *
116  * <p>This class also provides convenience methods to {@link
117  * #acquire(int) acquire} and {@link #release(int) release} multiple
118  * permits at a time.  Beware of the increased risk of indefinite
119  * postponement when these methods are used without fairness set true.
120  *
121  * <p>Memory consistency effects: Actions in a thread prior to calling
122  * a "release" method such as {@code release()}
123  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
124  * actions following a successful "acquire" method such as {@code acquire()}
125  * in another thread.
126  *
127  * @since 1.5
128  * @author Doug Lea
129  *
130  */
131
132 public class Semaphore implements /*java.io.*/Serializable {
133     private static final long serialVersionUID = -3222578661600680210L;
134     /** All mechanics via AbstractQueuedSynchronizer subclass */
135     //private final Sync sync;
136
137     /**
138      * Synchronization implementation for semaphore.  Uses AQS state
139      * to represent permits. Subclassed into fair and nonfair
140      * versions.
141      */
142    /* abstract static class Sync extends AbstractQueuedSynchronizer {
143         private static final long serialVersionUID = 1192457210091910933L;
144
145         Sync(int permits) {
146             setState(permits);
147         }
148
149         final int getPermits() {
150             return getState();
151         }
152
153         final int nonfairTryAcquireShared(int acquires) {
154             for (;;) {
155                 int available = getState();
156                 int remaining = available - acquires;
157                 if (remaining < 0 ||
158                     compareAndSetState(available, remaining))
159                     return remaining;
160             }
161         }
162
163         protected final boolean tryReleaseShared(int releases) {
164             for (;;) {
165                 int p = getState();
166                 if (compareAndSetState(p, p + releases))
167                     return true;
168             }
169         }
170
171         final void reducePermits(int reductions) {
172             for (;;) {
173                 int current = getState();
174                 int next = current - reductions;
175                 if (compareAndSetState(current, next))
176                     return;
177             }
178         }
179
180         final int drainPermits() {
181             for (;;) {
182                 int current = getState();
183                 if (current == 0 || compareAndSetState(current, 0))
184                     return current;
185             }
186         }
187     }*/
188
189     /**
190      * NonFair version
191      */
192     /*final static class NonfairSync extends Sync {
193         private static final long serialVersionUID = -2694183684443567898L;
194
195         NonfairSync(int permits) {
196             super(permits);
197         }
198
199         protected int tryAcquireShared(int acquires) {
200             return nonfairTryAcquireShared(acquires);
201         }
202     }*/
203
204     /**
205      * Fair version
206      */
207     /*final static class FairSync extends Sync {
208         private static final long serialVersionUID = 2014338818796000944L;
209
210         FairSync(int permits) {
211             super(permits);
212         }
213
214         protected int tryAcquireShared(int acquires) {
215             Thread current = Thread.currentThread();
216             for (;;) {
217                 Thread first = getFirstQueuedThread();
218                 if (first != null && first != current)
219                     return -1;
220                 int available = getState();
221                 int remaining = available - acquires;
222                 if (remaining < 0 ||
223                     compareAndSetState(available, remaining))
224                     return remaining;
225             }
226         }
227     }*/
228
229     /**
230      * Creates a {@code Semaphore} with the given number of
231      * permits and nonfair fairness setting.
232      *
233      * @param permits the initial number of permits available.
234      *        This value may be negative, in which case releases
235      *        must occur before any acquires will be granted.
236      */
237     public Semaphore(int permits) {
238         //sync = new NonfairSync(permits);
239     }
240
241     /**
242      * Creates a {@code Semaphore} with the given number of
243      * permits and the given fairness setting.
244      *
245      * @param permits the initial number of permits available.
246      *        This value may be negative, in which case releases
247      *        must occur before any acquires will be granted.
248      * @param fair {@code true} if this semaphore will guarantee
249      *        first-in first-out granting of permits under contention,
250      *        else {@code false}
251      */
252     public Semaphore(int permits, boolean fair) {
253         //sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
254     }
255
256     /**
257      * Acquires a permit from this semaphore, blocking until one is
258      * available, or the thread is {@linkplain Thread#interrupt interrupted}.
259      *
260      * <p>Acquires a permit, if one is available and returns immediately,
261      * reducing the number of available permits by one.
262      *
263      * <p>If no permit is available then the current thread becomes
264      * disabled for thread scheduling purposes and lies dormant until
265      * one of two things happens:
266      * <ul>
267      * <li>Some other thread invokes the {@link #release} method for this
268      * semaphore and the current thread is next to be assigned a permit; or
269      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
270      * the current thread.
271      * </ul>
272      *
273      * <p>If the current thread:
274      * <ul>
275      * <li>has its interrupted status set on entry to this method; or
276      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
277      * for a permit,
278      * </ul>
279      * then {@link InterruptedException} is thrown and the current thread's
280      * interrupted status is cleared.
281      *
282      * @throws InterruptedException if the current thread is interrupted
283      */
284     public void acquire() throws InterruptedException {
285         //sync.acquireSharedInterruptibly(1);
286         System.out.println("Unimplemented Semaphore.acquire()!");
287     }
288
289     /**
290      * Acquires a permit from this semaphore, blocking until one is
291      * available.
292      *
293      * <p>Acquires a permit, if one is available and returns immediately,
294      * reducing the number of available permits by one.
295      *
296      * <p>If no permit is available then the current thread becomes
297      * disabled for thread scheduling purposes and lies dormant until
298      * some other thread invokes the {@link #release} method for this
299      * semaphore and the current thread is next to be assigned a permit.
300      *
301      * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
302      * while waiting for a permit then it will continue to wait, but the
303      * time at which the thread is assigned a permit may change compared to
304      * the time it would have received the permit had no interruption
305      * occurred.  When the thread does return from this method its interrupt
306      * status will be set.
307      */
308     /*public void acquireUninterruptibly() {
309         sync.acquireShared(1);
310     }*/
311
312     /**
313      * Acquires a permit from this semaphore, only if one is available at the
314      * time of invocation.
315      *
316      * <p>Acquires a permit, if one is available and returns immediately,
317      * with the value {@code true},
318      * reducing the number of available permits by one.
319      *
320      * <p>If no permit is available then this method will return
321      * immediately with the value {@code false}.
322      *
323      * <p>Even when this semaphore has been set to use a
324      * fair ordering policy, a call to {@code tryAcquire()} <em>will</em>
325      * immediately acquire a permit if one is available, whether or not
326      * other threads are currently waiting.
327      * This &quot;barging&quot; behavior can be useful in certain
328      * circumstances, even though it breaks fairness. If you want to honor
329      * the fairness setting, then use
330      * {@link #tryAcquire(long, TimeUnit) tryAcquire(0, TimeUnit.SECONDS) }
331      * which is almost equivalent (it also detects interruption).
332      *
333      * @return {@code true} if a permit was acquired and {@code false}
334      *         otherwise
335      */
336     /*public boolean tryAcquire() {
337         return sync.nonfairTryAcquireShared(1) >= 0;
338     }*/
339
340     /**
341      * Acquires a permit from this semaphore, if one becomes available
342      * within the given waiting time and the current thread has not
343      * been {@linkplain Thread#interrupt interrupted}.
344      *
345      * <p>Acquires a permit, if one is available and returns immediately,
346      * with the value {@code true},
347      * reducing the number of available permits by one.
348      *
349      * <p>If no permit is available then the current thread becomes
350      * disabled for thread scheduling purposes and lies dormant until
351      * one of three things happens:
352      * <ul>
353      * <li>Some other thread invokes the {@link #release} method for this
354      * semaphore and the current thread is next to be assigned a permit; or
355      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
356      * the current thread; or
357      * <li>The specified waiting time elapses.
358      * </ul>
359      *
360      * <p>If a permit is acquired then the value {@code true} is returned.
361      *
362      * <p>If the current thread:
363      * <ul>
364      * <li>has its interrupted status set on entry to this method; or
365      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
366      * to acquire a permit,
367      * </ul>
368      * then {@link InterruptedException} is thrown and the current thread's
369      * interrupted status is cleared.
370      *
371      * <p>If the specified waiting time elapses then the value {@code false}
372      * is returned.  If the time is less than or equal to zero, the method
373      * will not wait at all.
374      *
375      * @param timeout the maximum time to wait for a permit
376      * @param unit the time unit of the {@code timeout} argument
377      * @return {@code true} if a permit was acquired and {@code false}
378      *         if the waiting time elapsed before a permit was acquired
379      * @throws InterruptedException if the current thread is interrupted
380      */
381     /*public boolean tryAcquire(long timeout, TimeUnit unit)
382         throws InterruptedException {
383         return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
384     }*/
385
386     /**
387      * Releases a permit, returning it to the semaphore.
388      *
389      * <p>Releases a permit, increasing the number of available permits by
390      * one.  If any threads are trying to acquire a permit, then one is
391      * selected and given the permit that was just released.  That thread
392      * is (re)enabled for thread scheduling purposes.
393      *
394      * <p>There is no requirement that a thread that releases a permit must
395      * have acquired that permit by calling {@link #acquire}.
396      * Correct usage of a semaphore is established by programming convention
397      * in the application.
398      */
399     public void release() {
400         //sync.releaseShared(1);
401         System.out.println("Unimplemented Semaphore.release()!");
402     }
403
404     /**
405      * Acquires the given number of permits from this semaphore,
406      * blocking until all are available,
407      * or the thread is {@linkplain Thread#interrupt interrupted}.
408      *
409      * <p>Acquires the given number of permits, if they are available,
410      * and returns immediately, reducing the number of available permits
411      * by the given amount.
412      *
413      * <p>If insufficient permits are available then the current thread becomes
414      * disabled for thread scheduling purposes and lies dormant until
415      * one of two things happens:
416      * <ul>
417      * <li>Some other thread invokes one of the {@link #release() release}
418      * methods for this semaphore, the current thread is next to be assigned
419      * permits and the number of available permits satisfies this request; or
420      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
421      * the current thread.
422      * </ul>
423      *
424      * <p>If the current thread:
425      * <ul>
426      * <li>has its interrupted status set on entry to this method; or
427      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
428      * for a permit,
429      * </ul>
430      * then {@link InterruptedException} is thrown and the current thread's
431      * interrupted status is cleared.
432      * Any permits that were to be assigned to this thread are instead
433      * assigned to other threads trying to acquire permits, as if
434      * permits had been made available by a call to {@link #release()}.
435      *
436      * @param permits the number of permits to acquire
437      * @throws InterruptedException if the current thread is interrupted
438      * @throws IllegalArgumentException if {@code permits} is negative
439      */
440     public void acquire(int permits) throws InterruptedException {
441         /*if (permits < 0) throw new IllegalArgumentException();
442         sync.acquireSharedInterruptibly(permits);*/
443       System.out.println("Unimplemented Semaphore.acquire(int)!");
444     }
445
446     /**
447      * Acquires the given number of permits from this semaphore,
448      * blocking until all are available.
449      *
450      * <p>Acquires the given number of permits, if they are available,
451      * and returns immediately, reducing the number of available permits
452      * by the given amount.
453      *
454      * <p>If insufficient permits are available then the current thread becomes
455      * disabled for thread scheduling purposes and lies dormant until
456      * some other thread invokes one of the {@link #release() release}
457      * methods for this semaphore, the current thread is next to be assigned
458      * permits and the number of available permits satisfies this request.
459      *
460      * <p>If the current thread is {@linkplain Thread#interrupt interrupted}
461      * while waiting for permits then it will continue to wait and its
462      * position in the queue is not affected.  When the thread does return
463      * from this method its interrupt status will be set.
464      *
465      * @param permits the number of permits to acquire
466      * @throws IllegalArgumentException if {@code permits} is negative
467      *
468      */
469     /*public void acquireUninterruptibly(int permits) {
470         if (permits < 0) throw new IllegalArgumentException();
471         sync.acquireShared(permits);
472     }*/
473
474     /**
475      * Acquires the given number of permits from this semaphore, only
476      * if all are available at the time of invocation.
477      *
478      * <p>Acquires the given number of permits, if they are available, and
479      * returns immediately, with the value {@code true},
480      * reducing the number of available permits by the given amount.
481      *
482      * <p>If insufficient permits are available then this method will return
483      * immediately with the value {@code false} and the number of available
484      * permits is unchanged.
485      *
486      * <p>Even when this semaphore has been set to use a fair ordering
487      * policy, a call to {@code tryAcquire} <em>will</em>
488      * immediately acquire a permit if one is available, whether or
489      * not other threads are currently waiting.  This
490      * &quot;barging&quot; behavior can be useful in certain
491      * circumstances, even though it breaks fairness. If you want to
492      * honor the fairness setting, then use {@link #tryAcquire(int,
493      * long, TimeUnit) tryAcquire(permits, 0, TimeUnit.SECONDS) }
494      * which is almost equivalent (it also detects interruption).
495      *
496      * @param permits the number of permits to acquire
497      * @return {@code true} if the permits were acquired and
498      *         {@code false} otherwise
499      * @throws IllegalArgumentException if {@code permits} is negative
500      */
501     /*public boolean tryAcquire(int permits) {
502         if (permits < 0) throw new IllegalArgumentException();
503         return sync.nonfairTryAcquireShared(permits) >= 0;
504     }*/
505
506     /**
507      * Acquires the given number of permits from this semaphore, if all
508      * become available within the given waiting time and the current
509      * thread has not been {@linkplain Thread#interrupt interrupted}.
510      *
511      * <p>Acquires the given number of permits, if they are available and
512      * returns immediately, with the value {@code true},
513      * reducing the number of available permits by the given amount.
514      *
515      * <p>If insufficient permits are available then
516      * the current thread becomes disabled for thread scheduling
517      * purposes and lies dormant until one of three things happens:
518      * <ul>
519      * <li>Some other thread invokes one of the {@link #release() release}
520      * methods for this semaphore, the current thread is next to be assigned
521      * permits and the number of available permits satisfies this request; or
522      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
523      * the current thread; or
524      * <li>The specified waiting time elapses.
525      * </ul>
526      *
527      * <p>If the permits are acquired then the value {@code true} is returned.
528      *
529      * <p>If the current thread:
530      * <ul>
531      * <li>has its interrupted status set on entry to this method; or
532      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
533      * to acquire the permits,
534      * </ul>
535      * then {@link InterruptedException} is thrown and the current thread's
536      * interrupted status is cleared.
537      * Any permits that were to be assigned to this thread, are instead
538      * assigned to other threads trying to acquire permits, as if
539      * the permits had been made available by a call to {@link #release()}.
540      *
541      * <p>If the specified waiting time elapses then the value {@code false}
542      * is returned.  If the time is less than or equal to zero, the method
543      * will not wait at all.  Any permits that were to be assigned to this
544      * thread, are instead assigned to other threads trying to acquire
545      * permits, as if the permits had been made available by a call to
546      * {@link #release()}.
547      *
548      * @param permits the number of permits to acquire
549      * @param timeout the maximum time to wait for the permits
550      * @param unit the time unit of the {@code timeout} argument
551      * @return {@code true} if all permits were acquired and {@code false}
552      *         if the waiting time elapsed before all permits were acquired
553      * @throws InterruptedException if the current thread is interrupted
554      * @throws IllegalArgumentException if {@code permits} is negative
555      */
556     /*public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
557         throws InterruptedException {
558         if (permits < 0) throw new IllegalArgumentException();
559         return sync.tryAcquireSharedNanos(permits, unit.toNanos(timeout));
560     }*/
561
562     /**
563      * Releases the given number of permits, returning them to the semaphore.
564      *
565      * <p>Releases the given number of permits, increasing the number of
566      * available permits by that amount.
567      * If any threads are trying to acquire permits, then one
568      * is selected and given the permits that were just released.
569      * If the number of available permits satisfies that thread's request
570      * then that thread is (re)enabled for thread scheduling purposes;
571      * otherwise the thread will wait until sufficient permits are available.
572      * If there are still permits available
573      * after this thread's request has been satisfied, then those permits
574      * are assigned in turn to other threads trying to acquire permits.
575      *
576      * <p>There is no requirement that a thread that releases a permit must
577      * have acquired that permit by calling {@link Semaphore#acquire acquire}.
578      * Correct usage of a semaphore is established by programming convention
579      * in the application.
580      *
581      * @param permits the number of permits to release
582      * @throws IllegalArgumentException if {@code permits} is negative
583      */
584     public void release(int permits) {
585         /*if (permits < 0) throw new IllegalArgumentException();
586         sync.releaseShared(permits);*/
587       System.out.println("Unimplemented Semaphore.release()!");
588     }
589
590     /**
591      * Returns the current number of permits available in this semaphore.
592      *
593      * <p>This method is typically used for debugging and testing purposes.
594      *
595      * @return the number of permits available in this semaphore
596      */
597     /*public int availablePermits() {
598         return sync.getPermits();
599     }*/
600
601     /**
602      * Acquires and returns all permits that are immediately available.
603      *
604      * @return the number of permits acquired
605      */
606     /*public int drainPermits() {
607         return sync.drainPermits();
608     }*/
609
610     /**
611      * Shrinks the number of available permits by the indicated
612      * reduction. This method can be useful in subclasses that use
613      * semaphores to track resources that become unavailable. This
614      * method differs from {@code acquire} in that it does not block
615      * waiting for permits to become available.
616      *
617      * @param reduction the number of permits to remove
618      * @throws IllegalArgumentException if {@code reduction} is negative
619      */
620     /*protected void reducePermits(int reduction) {
621         if (reduction < 0) throw new IllegalArgumentException();
622         sync.reducePermits(reduction);
623     }*/
624
625     /**
626      * Returns {@code true} if this semaphore has fairness set true.
627      *
628      * @return {@code true} if this semaphore has fairness set true
629      */
630     /*public boolean isFair() {
631         return sync instanceof FairSync;
632     }*/
633
634     /**
635      * Queries whether any threads are waiting to acquire. Note that
636      * because cancellations may occur at any time, a {@code true}
637      * return does not guarantee that any other thread will ever
638      * acquire.  This method is designed primarily for use in
639      * monitoring of the system state.
640      *
641      * @return {@code true} if there may be other threads waiting to
642      *         acquire the lock
643      */
644     /*public final boolean hasQueuedThreads() {
645         return sync.hasQueuedThreads();
646     }*/
647
648     /**
649      * Returns an estimate of the number of threads waiting to acquire.
650      * The value is only an estimate because the number of threads may
651      * change dynamically while this method traverses internal data
652      * structures.  This method is designed for use in monitoring of the
653      * system state, not for synchronization control.
654      *
655      * @return the estimated number of threads waiting for this lock
656      */
657     /*public final int getQueueLength() {
658         return sync.getQueueLength();
659     }*/
660
661     /**
662      * Returns a collection containing threads that may be waiting to acquire.
663      * Because the actual set of threads may change dynamically while
664      * constructing this result, the returned collection is only a best-effort
665      * estimate.  The elements of the returned collection are in no particular
666      * order.  This method is designed to facilitate construction of
667      * subclasses that provide more extensive monitoring facilities.
668      *
669      * @return the collection of threads
670      */
671     /*protected Collection<Thread> getQueuedThreads() {
672         return sync.getQueuedThreads();
673     }*/
674
675     /**
676      * Returns a string identifying this semaphore, as well as its state.
677      * The state, in brackets, includes the String {@code "Permits ="}
678      * followed by the number of permits.
679      *
680      * @return a string identifying this semaphore, as well as its state
681      */
682     /*public String toString() {
683         return super.toString() + "[Permits = " + sync.getPermits() + "]";
684     }*/
685 }