
com.thesett.common.util.concurrent.BooleanLatch Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of common Show documentation
Show all versions of common Show documentation
My common library, a mixed bag of re-usable utility code.
The newest version!
/*
* Copyright The Sett Ltd, 2005 to 2014.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thesett.common.util.concurrent;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
/**
* A BooleanLatch is like a set of traffic lights, where threads can wait at a red light until another thread gives the
* green light. When threads arrive at the latch it is initially red. They queue up until the green signal is given, at
* which point they can all acquire the latch in shared mode and continue to run concurrently. Once the latch is
* signalled it cannot be reset to red again.
*
* The latch uses a {@link java.util.concurrent.locks.AbstractQueuedSynchronizer} to implement its synchronization.
* This has two internal states, 0 which means that the latch is blocked, and 1 which means that the latch is open.
*
*
CRC Card
* Responsibilities Collaborations
* Block threads until a go signal is given.
*
*
* @author Rupert Smith
*/
public class BooleanLatch
{
/** Holds the synchronizer that provides the thread queueing synchronization. */
private final Sync sync = new Sync();
/**
* Tests whether or not the latch has been signalled, that is to say that, the light is green.
*
* This method is non-blocking.
*
* @return true if the latch may be acquired; the light is green.
*/
public boolean isSignalled()
{
return sync.isSignalled();
}
/**
* Waits on the latch until the signal is given and the light is green. If the light is already green then the latch
* will be acquired and the thread will not have to wait.
*
* This method will block until the go signal is given or the thread is otherwise interrupted. Before carrying
* out any processing threads that return from this method should confirm that the go signal has really been given
* on this latch by calling the {@link #isSignalled()} method.
*/
public void await()
{
sync.acquireShared(1);
}
/**
* Releases any threads currently waiting on the latch. This flips the light to green allowing any threads that were
* waiting for this condition to now run.
*
* This method is non-blocking.
*/
public void signal()
{
sync.releaseShared(1);
}
/**
* Implements a thread queued synchronizer. The internal state 0 means that the queue is blocked and the internl
* state 1 means that the queue is released and that all waiting threads can acquire the synchronizer in shared
* mode.
*/
private static class Sync extends AbstractQueuedSynchronizer
{
/**
* Attempts to acquire this synchronizer in shared mode. It may be acquired once it has been released.
*
* @param ignore This parameter is ignored.
*
* @return 1 if the shared acquisition succeeds and -1 if it fails.
*/
protected int tryAcquireShared(int ignore)
{
return isSignalled() ? 1 : -1;
}
/**
* Releases the synchronizer, setting its internal state to 1.
*
* @param ignore This parameter is ignored.
*
* @return true always.
*/
protected boolean tryReleaseShared(int ignore)
{
setState(1);
return true;
}
/**
* Tests if the synchronizer is signalled. It is signalled when its internal state it 1.
*
* @return true if the internal state is 1, false otherwise.
*/
boolean isSignalled()
{
return getState() != 0;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy