blob: eeda32a7d2670f24cc67b1b465da4dd0682c5810 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 threaddemo.locking;
// XXX add support for read/writeSoon(Runnable)?
// XXX why bother with InvocationTargetException?
/**
* Some kind of a lock, with support for possible read and write modes.
* <P>
* Examples of use:
*
* <pre>
* Lock m = Locks.readWriteLock("foo", 0);
*
* // Grant write access, compute an integer and return it:
* return m.write(new LockAction<Integer>() {
* public Integer run() {
* return 1;
* }
* });
*
* // Obtain read access, do some computation, possibly throw an IOException:
* m.read(new LockExceptionAction<Void,IOException>() {
* public Void run() throws IOException {
* if (...) throw new IOException();
* return null;
* }
* });
* </pre>
*
* @see Locks
* @author Jesse Glick
*/
public interface RWLock {
/** Run an action only with read access.
* @param action the action to perform
* @return the object returned from {@link LockAction#run}
*/
<T> T read(LockAction<T> action);
/** Run an action with read access and possibly throw a checked exception.
* Note that <em>runtime exceptions</em> are always passed through, and neither
* require this invocation style, nor are encapsulated.
* @param action the action to execute
* @return the object returned from {@link LockExceptionAction#run}
* @throws E a checked exception, if any
* @throws RuntimeException if any runtime exception is thrown from the run method
* @see #read(LockAction)
*/
<T, E extends Exception> T read(LockExceptionAction<T, E> action) throws E;
/** Run an action with read access, returning no result.
* @param action the action to perform
* @see #read(LockAction)
*/
void read(Runnable action);
/**
* Run an action asynch with read access.
* @param action the action to perform
* @see #read(Runnable)
*/
void readLater(Runnable action);
/**
* Run an action with write access.
* <p><strong>May not be called while holding read access.</strong>
* @param action the action to perform
* @return the result of {@link LockAction#run}
*/
<T> T write(LockAction<T> action);
/**
* Run an action with write access and possibly throw an exception.
* <p><strong>May not be called while holding read access.</strong>
* @param action the action to execute
* @return the result of {@link LockExceptionAction#run}
* @throws E a checked exception, if any
* @throws RuntimeException if a runtime exception is thrown in the action
* @see #write(LockAction)
* @see #read(LockExceptionAction)
*/
<T, E extends Exception> T write(LockExceptionAction<T, E> action) throws E;
/**
* Run an action with write access and return no result.
* @param action the action to perform
* @see #write(LockAction)
* @see #read(Runnable)
*/
void write(Runnable action);
/**
* Run an action asynchronously with write access.
* @param action the action to perform
* @see #write(LockAction)
* @see #readLater(Runnable)
*/
void writeLater(Runnable action);
/**
* Check if the current thread is holding a read or write lock.
* @return true if either read or write access is available
*/
boolean canRead();
/**
* Check if the current thread is holding the write lock.
* Note that this will be false in case write access was entered and then
* read access was entered inside of that, until the nested read access is
* again exited.
* @return true if write access is available
*/
boolean canWrite();
}