深入解析:线程安全相关的注解

      主要有下面三个加在类上的线程安全相关的注解。

一.@Immutable

        标记一个类为不可变的。这意味着该类的实例在构造完成后,其状态(数据)永远不能被更改。实现不可变性的严格条件(Java内存模型中的定义):

  1. 所有字段都是 final 的:这确保了在构造函数执行完毕后,所有字段的引用对其他线程是可见的(通过 final 的语义保障),并且引用不能再指向其他对象。

  2. 类本身被声明为 final:防止子类覆盖其方法并意外地改变状态(“破坏性继承”)。

  3. this 引用没有逸出:在构造函数执行期间,this 引用不能提供给其他代码,防止其他代码在对象完全构造之前就看到它。

  4. 对可变状态的正确管理

    如果类包含对可变对象的引用(例如,一个 final List<String>),那么必须:
  • 如果需要返回内部可变状态,返回其防御性拷贝,而不是原始引用。
  • 不要提供任何可以修改这些可变状态的方法(如setter)。
  • 在构造函数中,深度拷贝任何传入的可变参数,而不是直接存储其引用。

下面是注解源码:

       可以发现有两个地方存在@Immutable注解,它们的来源不一样,我们应该使用第一个并发包下的注解。第二个不太稳定。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.annotation.concurrent;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Immutable {
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package jdk.nashorn.internal.ir.annotations;
public @interface Immutable {
}

总结

  • javax.annotation.concurrent.Immutable:是公共的、受支持的、有用的并发编程工具注解,用于文档化和静态分析。

  • jdk.nashorn.internal.ir.annotations.Immutable:是内部的、已废弃的、特化的JDK实现细节注解,与应用程序开发无关。

二.@ThreadSafe

       标记一个类是线程安全的。这意味着该类的实例可以在多线程环境下被安全地并发使用,其内部方法会维护状态的一致性。

实现方式(多种途径):

  1. 无状态:类没有任何字段,自然是线程安全的。(如:只包含静态工具方法的类)。

  2. 使用不可变状态:即类本身是 @Immutable 的。

  3. 使用内置锁 (synchronized):通过同步方法或同步代码块来保护所有访问状态的临界区。

  4. 使用并发容器:例如,使用 ConcurrentHashMap 代替 HashMap,使用 AtomicInteger 代替 int

  5. 使用显式锁 (java.util.concurrent.locks.Lock):提供更灵活的锁定机制。

       下面是concurrent包下的注解源码。(其实java中还有别的@ThreadSafe注解,问题与上面一个注解类似,有不同的来源,主要使用下面这个)

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.annotation.concurrent;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface ThreadSafe {
}

三.@NotThreadSafe

       明确标记一个类是非线程安全的。这意味着该类的实例不能在多线程间共享,除非由调用者通过外部手段(如外部同步)来协调访问。

为什么需要它?

  • 默认情况:Java中的大多数类(如 ArrayListHashMapStringBuilder)默认都是非线程安全的,以实现最佳性能。

  • 明确警示:加上此注解是一个非常好的实践,它明确地告诉使用者:“注意!这个类不是线程安全的,你不能直接在多线程环境下使用它”,避免了潜在的误用和难以发现的并发Bug。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package javax.annotation.concurrent;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface NotThreadSafe {
}
posted @ 2025-09-21 17:23  wzzkaifa  阅读(11)  评论(0)    收藏  举报