All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.atlassian.util.concurrent.BooleanLatch Maven / Gradle / Ivy

Go to download

This project contains utility classes that are used by various products and projects inside Atlassian and may have some utility to the world at large.

There is a newer version: 4.0.1
Show newest version
/**
 * Copyright 2008 Atlassian Pty Ltd 
 * 
 * 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 io.atlassian.util.concurrent;

import net.jcip.annotations.ThreadSafe;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * A {@link io.atlassian.util.concurrent.BooleanLatch} is a reusable latch that
 * resets after it is released and waited on. It depends on a boolean condition
 * of being released or not and becomes unreleased when one thread successfully
 * awaits it. It is useful for rally like release-wait-release coordination, and
 * as a replacement to waiting on a {@link java.util.concurrent.locks.Condition}
 * (it should be faster as the write thread does not need to acquire a lock in
 * order to signal.
 * 

* This latch is suitable for SRSW coordination. MRSW is supported but has the * same semantics as {@link java.util.concurrent.locks.Condition#signal()}, that * is to say that {@link java.util.concurrent.locks.Condition#signalAll()} is * not supported and if there are multiple waiters then the particular thread * that is released is arbitrary. */ @ThreadSafe public class BooleanLatch implements ReusableLatch { /** * Synchronization control For BooleanLatch. Uses AQS state to represent * released state. */ private static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -3475411235403448115L; private static final int RELEASED = 0; private static final int UNAVAILABLE = -1; private Sync() { setState(UNAVAILABLE); } @Override protected boolean tryAcquire(final int ignore) { if (!(getState() == RELEASED)) { return false; } return compareAndSetState(RELEASED, UNAVAILABLE); } @Override protected boolean tryRelease(final int ignore) { final int state = getState(); if (state == UNAVAILABLE) { setState(RELEASED); } return true; } } private final Sync sync = new Sync(); /** * {@inheritDoc} * * Releases at most one waiting thread. If the current state is released then * nothing happens. */ public final void release() { sync.release(0); } /** * {@inheritDoc} * * Causes the current thread to wait until the latch has been released, unless * the thread is {@linkplain Thread#interrupt() interrupted}. *

* If the latch has already been released then this method returns * immediately. *

* If the latch is not released then the current thread becomes disabled for * thread scheduling purposes and lies dormant until one of two things happen: *

    *
  • The latch is released by another thread invoking the {@link #release()} * method; or *
  • Some other thread {@linkplain Thread#interrupt interrupts} the current * thread. *
*

* If the current thread: *

    *
  • has its interrupted status set on entry to this method; or *
  • is {@linkplain Thread#interrupt interrupted} while waiting, *
* then {@link java.lang.InterruptedException} is thrown and the current * thread's interrupted status is cleared. * * @throws java.lang.InterruptedException if the current thread is interrupted * while waiting */ public final void await() throws InterruptedException { sync.acquireInterruptibly(0); } /** * {@inheritDoc} * * Causes the current thread to wait until the latch has been released, unless * the thread is {@linkplain Thread#interrupt() interrupted}, or the specified * waiting time elapses. *

* If the latch has already been released then this method returns immediately * with return value true. *

* If the latch is unreleased then the current thread becomes disabled for * thread scheduling purposes and lies dormant until one of three things * happen: *

    *
  • The latch is released by another thread invoking the {@link #release()} * method; or *
  • Some other thread {@linkplain Thread#interrupt interrupts} the current * thread; or *
  • The specified waiting time elapses. *
*

* If latch is released by another thread then the method returns with the * value {@code true}. *

* If the current thread: *

    *
  • has its interrupted status set on entry to this method; or *
  • is {@linkplain Thread#interrupt interrupted} while waiting, *
* then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. *

* If the specified waiting time elapses then the value {@code false} is * returned. If the time is less than or equal to zero, the method will not * wait at all. */ public final boolean await(final long timeout, final TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(0, unit.toNanos(timeout)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy