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

org.microbean.lang.CompletionLock Maven / Gradle / Ivy

There is a newer version: 0.0.20
Show newest version
/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
 *
 * Copyright © 2022–2024 microBean™.
 *
 * 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 org.microbean.lang;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import java.util.function.BooleanSupplier;
import java.util.function.Supplier;

/**
 * A utility class logically containing a single {@link Lock} that is used to guard against concurrent symbol
 * completion.
 *
 * 

The {@code javax.lang.model.*} classes make no guarantees about thread safety. Certain operations on {@link * javax.lang.model.type.TypeMirror} and {@link javax.lang.model.element.Element}, particularly {@link * javax.lang.model.type.TypeMirror#getKind()} and {@link javax.lang.model.element.Element#getKind()} operations, will * result in symbol completion, which may involve modification of the {@link javax.lang.model.type.TypeMirror} or {@link * javax.lang.model.element.Element} in question. It is imperative that this modification be performed under global lock * if thread safety is to be preserved, and that is the function of this class.

* *

Note that {@link org.microbean.lang.type.DelegatingTypeMirror} and {@link * org.microbean.lang.element.DelegatingElement} automatically perform such locking, and all operations in {@link Lang} * that could result in symbol completion also perform such locking.

* * @author Laird Nelson * * @see #acquire() * * @see #release() */ public final class CompletionLock { /* * Static fields. */ private static final long serialVersionUID = 1L; private static final Lock LOCK = new ReentrantLock(); /* * Constructors. */ private CompletionLock() { super(); } /* * Static methods. */ /** * Calls {@link Lock#lock() lock()} on the global {@link Lock} and returns it. * * @return the locked {@link Lock}; never {@code null} * * @see #release() */ public static final Lock acquire() { LOCK.lock(); return LOCK; } /** * Calls {@link Lock#unlock() unlock()} on the global {@link Lock} and returns it. * * @return the unlocked {@link Lock}; never {@code null} * * @see #acquire() */ public static final Lock release() { LOCK.unlock(); return LOCK; } /** * Calls {@link #acquire()}, then {@link Supplier#get() get()} on the supplied {@link Supplier}, then {@link * #release()} in a {@code finally} block, and returns the result of the {@link Supplier#get() get()} invocation. * * @param the type of the object this method will return * * @param s a {@link Supplier}; must not be {@code null} * * @return the result of an invocation of the supplied {@link Supplier}'s {@link Supplier#get() get()} method, which * may be {@code null} * * @exception NullPointerException if {@code s} is {@code null} */ public static final T guard(final Supplier s) { acquire(); try { return s.get(); } finally { release(); } } /** * Calls {@link #acquire()}, then {@link Supplier#get() get()} on the supplied {@link BooleanSupplier}, then {@link * #release()} in a {@code finally} block, and returns the result of the {@link BooleanSupplier#getAsBoolean() * getAsBoolean()} invocation. * * @param s a {@link BooleanSupplier}; must not be {@code null} * * @return the result of an invocation of the supplied {@link BooleanSupplier}'s {@link BooleanSupplier#getAsBoolean() * getAsBoolean()} method * * @exception NullPointerException if {@code s} is {@code null} */ public static final boolean guard(final BooleanSupplier s) { acquire(); try { return s.getAsBoolean(); } finally { release(); } } /** * Calls {@link #acquire()}, then {@link Runnable#run() run()} on the supplied {@link Supplier}, then {@link * #release()} in a {@code finally} block. * * @param r a {@link Runnable}; must not be {@code null} * * @exception NullPointerException if {@code r} is {@code null} */ public static final void guard(final Runnable r) { acquire(); try { r.run(); } finally { release(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy