/*
* 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 .
*/
package nsk.share;
import java.io.PrintStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 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 >
*/
public class Wicket {
/** Number of closed locks, can be greater or equal to zero */
private int count;
/** Number of waiters **/
private int waiters = 0 ;
/** Enable debug output */
private PrintStream debugOutput = null ;
/** Wicket's string identifier */
private String name = "" ;
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
/**
* 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 )
throw new 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 .
*/
public void 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);
}
while (count > 0 ) {
try {
condition.await();
} catch (InterruptedException e) {
}
}
--waiters;
} finally {
lock.unlock();
}
}
/**
* 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
*/
public int waitFor(long timeout) {
if (timeout < 0 )
throw new 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();
while (count > 0 && waitTime > 0 ) {
try {
condition.await(waitTime, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
waitTime = timeout - (System.currentTimeMillis() - startTime);
}
--waiters;
return count;
} finally {
lock.unlock();
}
}
/**
* 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
*/
public void unlock() {
lock.lock();
try {
if (count == 0 )
throw new IllegalStateException("locks are already open" );
--count;
if (debugOutput != null ) {
debugOutput.printf("Wicket %s: unlock() the count is now %d\n" , name, count);
}
if (count == 0 ) {
condition.signalAll();
}
} finally {
lock.unlock();
}
}
/**
* 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 .
*/
public void unlockAll() {
if (debugOutput != null ) {
debugOutput.printf("Wicket %s: unlockAll()\n" , name);
}
lock.lock();
try {
count = 0 ;
condition.signalAll();
} finally {
lock.unlock();
}
}
/**
* Return current number of waiters - threads that are currently
* waiting using one of waitFor methods .
*
* @ return number of waiters
*/
public int getWaiters() {
lock.lock();
try {
if (debugOutput != null ) {
debugOutput.printf("Wicket %s: getWaiters()\n" , name);
}
return waiters;
} finally {
lock.unlock();
}
}
}
Messung V0.5 in Prozent C=96 H=96 G=95
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland