groovy.transform.WithReadLock Maven / Gradle / Ivy
/*
* 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 groovy.transform;
import org.codehaus.groovy.transform.GroovyASTTransformationClass;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation is used in conjunction with {@link WithWriteLock} to support read and write synchronization on a method.
*
* To use this annotation, declare {@code @WithReadLock} on your method. The method may be either an instance method or
* a static method. The resulting method will allow multiple threads to read the information at the same time.
* However, if some other method obtains a write lock, then this method will force callers to wait until the write is complete.
*
* This annotation is a declarative wrapper around the JDK's java.util.concurrent.locks.ReentrantReadWriteLock
.
* Objects containing this annotation will have a ReentrantReadWriteLock field named $reentrantLock
added to the class,
* and method access is protected by the lock. If the method is static then the field is static and named $REENTRANTLOCK
.
*
* The annotation takes an optional parameter for the name of the field. This field must exist on the class and must be
* of type ReentrantReadWriteLock.
*
* To understand how this annotation works, it is convenient to think in terms of the source code it replaces. The following
* is a typical usage of this annotation from Groovy:
*
* import groovy.transform.*;
*
* public class ResourceProvider {
*
* private final Map<String, String> data = new HashMap<String, String>();
*
* {@code @WithReadLock}
* public String getResource(String key) throws Exception {
* return data.get(key);
* }
*
* {@code @WithWriteLock}
* public void refresh() throws Exception {
* //reload the resources into memory
* }
* }
*
* As part of the Groovy compiler, code resembling this is produced:
*
* import java.util.concurrent.locks.ReentrantReadWriteLock;
* import java.util.concurrent.locks.ReadWriteLock;
*
* public class ResourceProvider {
*
* private final ReadWriteLock $reentrantlock = new ReentrantReadWriteLock();
* private final Map<String, String> data = new HashMap<String, String>();
*
* public String getResource(String key) throws Exception {
* $reentrantlock.readLock().lock();
* try {
* return data.get(key);
* } finally {
* $reentrantlock.readLock().unlock();
* }
* }
*
* public void refresh() throws Exception {
* $reentrantlock.writeLock().lock();
* try {
* //reload the resources into memory
* } finally {
* $reentrantlock.writeLock().unlock();
* }
* }
* }
*
*
* @author Hamlet D'Arcy
* @since 1.8.0
*/
@java.lang.annotation.Documented
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD})
@GroovyASTTransformationClass("org.codehaus.groovy.transform.ReadWriteLockASTTransformation")
public @interface WithReadLock {
/**
* @return if a user specified lock object with the given name should be used
* the lock object must exist. If the annotated method is static then the
* lock object must be static. If the annotated method is not static then
* the lock object must not be static.
*/
String value () default "";
}