/* * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/** * Wicket provides a means for one or more threads to suspend execution * (to wait) until notified by one or more other threads that some set * of locks is now open. * * <p>Wicket instances are intended to be used generally in the following * scenarios: * * <ul><li>One thread starts one or more child threads and waits until the * child threads to be started. * * <li>One thread starts one or more child threads and waits until at least * one of the child threads to be started. * * <li>One or more child threads wait until a main thread lets them * to finish. * * <li>Disable the current thread for thread scheduling purposes, for up to * the specified waiting time.</ul>
*/
publicclass Wicket {
/** Number of closed locks, can be greater or equal to zero */ privateint count;
/** * Construct a Wicket with only one closed lock.
*/ public Wicket() { this(1);
}
/** * Construct a Wicket with the given number of closed locks. * * @param _name Wicket's identifier * @param _count the initial number of closed locks * @param _debugOutput whether to print debug info or not * @throws IllegalArgumentException if count is less than 1
*/ public Wicket(String _name, int _count, PrintStream _debugOutput) { this(_count);
name = _name;
debugOutput = _debugOutput;
}
/** * Construct a Wicket with the given number of closed locks. * * @param count the initial number of closed locks * @throws IllegalArgumentException if count is less than 1
*/ public Wicket(int count) { if (count < 1) thrownew IllegalArgumentException( "count is less than one: " + count); this.count = count;
}
/** * Wait for all locks of this Wicket to be open. * * <p>If all locks are already open then returns immediately. * * <p>If at least one lock is still closed then the current thread becomes * disabled for thread scheduling purposes and lies dormant until all * the locks will be open by some other threads. One lock can be open * by invoking the unlock method for this Wicket. * * <p>Please note, that the method would ignore Thread.interrupt() requests.
*/ publicvoid waitFor() { long id = System.currentTimeMillis();
lock.lock(); try {
++waiters; if (debugOutput != null) {
debugOutput.printf("Wicket %d %s: waitFor(). There are %d waiters totally now.\n", id, name, waiters);
}
/** * Wait for all locks of this Wicket to be open within the given * period of time. * * <p>If all locks are already open then returns immediately with zero. * * <p>If the time is equal to zero, the method will not * wait and returns a number of closed locks, * if all locks are open, the return value is zero. * * <p>If at least one lock is still closed then the current thread becomes * disabled for thread scheduling purposes and lies dormant until * of the two things happens: * * <ul><li>Some other threads invoke the unlock method for this Wicket * to open all the closed locks; or * * <li>The specified waiting time elapses.</ul> * * <p>If all locks are open then the return value is 0. * * <p>If the specified waiting time elapses and some locks are still closed * then the return value is equal to number of closed locks. * * <p>Please note, that the method would ignore Thread.interrupt() requests. * * @param timeout the maximum time to wait in milliseconds * @return the number of closed locks * @throws IllegalArgumentException if timeout is less than 0
*/ publicint waitFor(long timeout) { if (timeout < 0) thrownew IllegalArgumentException( "timeout value is negative: " + timeout);
long id = System.currentTimeMillis();
lock.lock(); try {
++waiters; if (debugOutput != null) {
debugOutput.printf("Wicket %d %s: waitFor(). There are %d waiters totally now.\n", id, name, waiters);
}
long waitTime = timeout; long startTime = System.currentTimeMillis();
/** * Unlock one closed lock. * * <p>Open a lock, reducing the number of closed locks by one. * * <p>If last closed lock is opened then all of the threads waiting * by invoking the waitFor method for this Wicket will be released * and re-enabled for thread scheduling purposes. * * @throws IllegalStateException if there is no one closed lock
*/ publicvoid unlock() {
lock.lock(); try { if (count == 0) thrownew IllegalStateException("locks are already open");
--count; if (debugOutput != null) {
debugOutput.printf("Wicket %s: unlock() the count is now %d\n", name, count);
}
/** * Unlock all closed locks. * * <p>Open all closed locks, setting the number of closed locks to zero. * * <p>If any threads are waiting by invoking the waitFor method for * this Wicket then they will be released and re-enabled for thread * scheduling purposes.
*/ publicvoid unlockAll() { if (debugOutput != null) {
debugOutput.printf("Wicket %s: unlockAll()\n", name);
}
/** * Return current number of waiters - threads that are currently * waiting using one of waitFor methods. * * @return number of waiters
*/ publicint getWaiters() {
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.