001/* 002 * Units of Measurement Reference Implementation 003 * Copyright (c) 2005-2021, Jean-Marie Dautelle, Werner Keil, Otavio Santana. 004 * 005 * All rights reserved. 006 * 007 * Redistribution and use in source and binary forms, with or without modification, 008 * are permitted provided that the following conditions are met: 009 * 010 * 1. Redistributions of source code must retain the above copyright notice, 011 * this list of conditions and the following disclaimer. 012 * 013 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions 014 * and the following disclaimer in the documentation and/or other materials provided with the distribution. 015 * 016 * 3. Neither the name of JSR-385, Indriya nor the names of their contributors may be used to endorse or promote products 017 * derived from this software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 021 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 023 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 026 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 028 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package tech.units.indriya.internal.function; 031 032import static org.apiguardian.api.API.Status.INTERNAL; 033 034import java.util.Objects; 035import java.util.function.Supplier; 036 037import org.apiguardian.api.API; 038 039/** 040 * Holder of an instance of type T, supporting the <em>compute-if-absent</em> idiom in a thread-safe manner. 041 * <p> 042 * Not serializable! 043 * 044 * @author Andi Huber 045 * @since 2.0.3 046 */ 047@API(status=INTERNAL) 048public class Lazy<T> { 049 private final Supplier<? extends T> supplier; 050 private T value; 051 private boolean memorized; 052 053 public Lazy(Supplier<? extends T> supplier) { 054 this.supplier = Objects.requireNonNull(supplier, "supplier is required"); 055 } 056 057 public boolean isMemorized() { 058 synchronized (this) { 059 return memorized; 060 } 061 } 062 063 public void clear() { 064 synchronized (this) { 065 this.memorized = false; 066 this.value = null; 067 } 068 } 069 070 public T get() { 071 synchronized (this) { 072 if(memorized) { 073 return value; 074 } 075 memorized = true; 076 return value = supplier.get(); 077 } 078 } 079 080 public void set(T value) { 081 synchronized (this) { 082 if(memorized) { 083 throw new IllegalStateException( 084 String.format("cannot set value '%s' on Lazy that has already memoized a value", ""+value)); 085 } 086 memorized = true; 087 this.value = value; 088 } 089 } 090}