001package org.eclipse.aether.named;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.concurrent.TimeUnit;
023
024/**
025 * A named lock, functionally similar to existing JVM and other implementations. Must support boxing (reentrancy), but
026 * no lock upgrade is supported. The lock instance obtained from lock factory must be treated as a resource, best in
027 * try-with-resource block. Usual pattern to use this lock:
028 * <pre>
029 *   try (NamedLock lock = factory.getLock("resourceName")) {
030 *     if (lock.lockExclusively(10L, Timeunit.SECONDS)) {
031 *       try {
032 *         ... exclusive access to "resourceName" resource gained here
033 *       }
034 *       finally {
035 *         lock.unlock();
036 *       }
037 *     }
038 *     else {
039 *       ... failed to gain access within specified time, handle it
040 *     }
041 *   }
042 * </pre>
043 */
044public interface NamedLock extends AutoCloseable
045{
046    /**
047     * Returns this instance name, never null
048     */
049    String name();
050
051    /**
052     * Tries to lock shared, may block for given time. If successful, returns {@code true}.
053     */
054    boolean lockShared( long time, TimeUnit unit ) throws InterruptedException;
055
056    /**
057     * Tries to lock exclusively, may block for given time. If successful, returns {@code true}.
058     */
059    boolean lockExclusively( long time, TimeUnit unit ) throws InterruptedException;
060
061    /**
062     * Unlocks the lock, must be invoked by caller after one of the {@link #lockShared(long, TimeUnit)} or {@link
063     * #lockExclusively(long, TimeUnit)}.
064     */
065    void unlock();
066
067    /**
068     * Closes the lock resource. Lock MUST be unlocked using {@link #unlock()} in case any locking happened on it. After
069     * invoking this method, the lock instance MUST NOT be used anymore. If lock for same name needed, a new instance
070     * should be obtained from factory using {@link NamedLockFactory#getLock(String)}. Ideally, instances are to be used
071     * within try-with-resource blocks, so calling this method directly is not really needed, nor advised.
072     */
073    @Override
074    void close();
075}