001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package net.tridentsdk.concurrent; 019 020import javax.annotation.concurrent.ThreadSafe; 021import java.util.concurrent.CountDownLatch; 022 023/** 024 * A one-time latch that holds a value 025 * 026 * @author The TridentSDK Team 027 * @since 0.3-alpha-DP 028 * @param <V> the value type of the latch 029 */ 030@ThreadSafe 031public class HeldValueLatch<V> { 032 private final CountDownLatch latch = new CountDownLatch(1); 033 private volatile V value; 034 035 private HeldValueLatch() { 036 } 037 038 /** 039 * Creates a new latch that can hold a value 040 * 041 * @param <V> the type of the value 042 * @return a new value latch 043 */ 044 public static <V> HeldValueLatch<V> create() { 045 return new HeldValueLatch<>(); 046 } 047 048 /** 049 * Sets the value in the latch 050 * 051 * <p>The effects of setting this only once is unspecified</p> 052 * 053 * <p>This is unsynchronized because all actions prior to counting down <em>happens-before</em> another thread 054 * awaits the value</p> 055 * 056 * @param value the value to set to the latch 057 * @return the value passed in 058 */ 059 public V countDown(V value) { 060 this.value = value; 061 latch.countDown(); 062 return value; 063 } 064 065 /** 066 * Inspects the latch to find of the object has been counted down 067 * 068 * @return {@code true} if the value has been set 069 */ 070 public boolean hasValue() { 071 return this.latch.getCount() == 0; 072 } 073 074 /** 075 * Acquires the value held be the latch, or blocks to wait for the value to become available 076 * 077 * @return the value held by the latch 078 * @throws InterruptedException if the operation was interrupted while blocked 079 */ 080 public V await() throws InterruptedException { 081 latch.await(); 082 return value; 083 } 084 085 /** 086 * Acquires the value without waiting for the latch to be counted down 087 * 088 * <p>This is still thread-safe, as the internal state is {@code volatile}</p> 089 * 090 * @return the value held by this latch 091 */ 092 public V get() { 093 return value; 094 } 095}