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

com.google.errorprone.annotations.ThreadSafe Maven / Gradle / Ivy

There is a newer version: 3.0.0-alpha-3
Show newest version
/*
 * Copyright 2023 The Error Prone Authors.
 *
 * 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 com.google.errorprone.annotations;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * This annotation indicates that the class/interface it is applied to is thread safe
 *
 * 

An object is thread safe if no sequences of accesses (like reads and writes to public fields * or calls to public methods) may put the object into an invalid state, or cause it to violate its * contract, regardless of the interleaving of those actions at runtime. * *

This annotation has two related-but-distinct purposes: * *

    *
  • For humans: it indicates that the class/interface (and subclasses) is thread-safe *
  • For machines: it causes the annotated class/interface -- and all of its subtypes -- to be * validated by the {@code com.google.errorprone.bugpatterns.threadsafety.ThreadSafeChecker} * {@code BugChecker}. *
* * Note that passing the checks performed by the {@code ThreadSafeChecker} is neither necessary nor * sufficient to guarantee the thread safety of a class. In fact, it is not possible to determine * thread safety through static code analysis alone, and the goal of {@code ThreadSafeChecker} is to * steer the code towards using standard thread-safe patterns, and then to assist the developer in * avoiding common mistakes. It is not meant as a substitute for diligent code review by a * knowledgeable developer. * *

Also note that the only easy way to guarantee thread-safety of a class is to make it * immutable, and you should do that whenever possible (or at the least, make as much of the class * be immutable). Otherwise, writing a thread-safe class is inherently tricky and error prone, and * keeping it thread-safe is even more so. * *

The remainder of this javadoc describes the heuristics enforced by {@code ThreadSafeChecker} * and the related {@code com.google.errorprone.bugpatterns.threadsafety.GuardedByChecker} and * {@code com.google.errorprone.bugpatterns.threadsafety.ImmutableChecker} on which the former * relies. * *

The {@code ThreadSafeChecker} heuristics enforce that every field meets at least one of these * requirements: * *

    *
  • It is both {@code final} and its type is deemed inherently deeply thread-safe; and/or *
  • it is annotated with either {@link com.google.errorprone.annotations.concurrent.GuardedBy} * (some other annotations named {@code GuardedBy} also work, though this the preferred); *
* * Below, more details about what is meant by "deemed inherently deeply thread-safe" are presented, * and, afterwards, more about {@code GuardedBy}. * *

A type is deemed inherently deeply thread-safe if it meets two requirements. The first * requirement is that it meets at least one of these four conditions: * *

    *
  • it is listed as a well-known immutable type in {@code * com.google.errorprone.bugpatterns.threadsafety.WellKnownMutability} (e.g. a field of type * {@link String}); and/or *
  • it is listed as a well-known thread-safe type in {@code * com.google.errorprone.bugpatterns.threadsafety.WellKnownThreadSafety} (e.g. a field of type * {@link java.util.concurrent.atomic.AtomicBoolean}); and/or *
  • it is annotated with {@link Immutable}; and/or *
  • it is annotated with {@link ThreadSafe}. *
* *

This first requirement means the type is at least inherently shallowly thread-safe. * *

Fields annotated with {@code javax.annotation.concurrent.GuardedBy} are likely the meat of a * mutable thread-safe class: these are things that need to be mutated, but should be done so in a * safe manner -- i.e., (most likely) in critical sections of code that protect their access by * means of a lock. See more information in that annotation's javadoc. * *

As stated before, the heuristics above are not sufficient to guarantee the thread safety of a * class. Also as stated before, thread-safety is tricky, and requires diligent analysis by skilled * people. That said, we provide here a few examples of common examples of ways to break these * heuristics, so as to help you avoid them: * *

    *
  • a non-private {@code @GuardedBy} field -- i.e.if a non-private {@code @GuardedBy} field is * accessed outside the class, the code that enforces {@code @GuardedBy} will not prevent * unprotected access and/or modifications to the field; *
  • indirect access to the field. There are several ways in which code may access the objects * stored in the field indirectly (i.e. not directly referencing the field). In all these * cases, {@code @GuardedBy} offers no enforcement. Here's some examples: *
      *
    • if the {@code @GuardedBy} field instance is part of an object by a method (e.g. a * simple getter method or constructor parameter); *
    • if a method takes an out-parameter and the method calls a method in that * out-parameter passing the instance of the {@code @GuardedBy} field, and that instance * is stored in the out-parameter (i.e. a simple setter method); *
    *
  • methods that perform multiple operations -- e.g., if a class {@code Foo} contains a {@code * AtomicInteger} (which is an inherently deeply thread-safe data structure), the following * code makes this class not thread-safe: *
    {@code
     * private void incrementMyAtomicInteger() {
     *   myAtomicInteger.set(myAtomicInteger.get() + 1);
     * }
     *
     * }
    *
* * Also see https://errorprone.info/bugpattern/ThreadSafe */ // TODO(b/112275411): when fixed, delete the comment above about non-private fields @Target({TYPE}) @Retention(RUNTIME) // Note: besides abiding by the standard behavior of `@Inherited`, the behavior enforced by // the static analysis effectively applies not only to classes that extend a class annotated with // @ThreadSafe but *also* applies to classes that implement an annotated interface. This is because // a class that implements an interface annotated with `@ThreadSafe` either: a. is anonymous, in // which case the static analysis is implemented to run against it; or b. it is not anonymous, in // which case the static analysis enforces that the class _also_ have an `@ThreadSafe` annotation. @Inherited @Documented public @interface ThreadSafe {}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy