当前位置: 首页 > news >正文

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

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

一.@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 {
}
http://www.jsqmd.com/news/1023/

相关文章:

  • go语言的结构体和指针
  • 通过主机监控发现路径遍历漏洞的实战技巧
  • Code New Roman 字体的正确下载方式
  • go语言中的数组类型
  • 多态是对于处理不同的变量,但是使用相同或者类似的方式。多态核心分为两种形式:编译时多态(静态多态)和运行时多态(动态多态)C++中多态通常使用虚函数或者指针(引用)实现。
  • 从 C++ 到 Python
  • 在 Unity 中实现 0GC(零垃圾回收)对象池 — 实战指南 - 实践
  • Nipper 3.9.0 for Windows Linux - 网络设备漏洞评估
  • c++单例实践
  • NOIP 模拟赛九
  • 个人项目-软件工程第二次作业 - Nyanya-
  • go语言中的复杂数据类型
  • 详细介绍:互联网医院品牌IP的用户体验和生态构建
  • 实用指南:认知语义学中的象似性对人工智能自然语言处理深层语义分析的影响与启示
  • 支持 SSL 中等强度密码组(SWEET32) - 漏洞检查与修复
  • C# WPF CommunityToolkit.MVVM (测试一)
  • linux kernel synchronization rcu
  • 完整教程:机器学习入门,用Lima在macOS免费搭建Docker环境,彻底解决镜像与收费难题!
  • go语言中的基本数据类型
  • 实用指南:rsync +生产级 lsyncd 实时同步方案
  • 锁定Nvidia驱动版本
  • 第二十一章-sql 注入-union 联合注入 (1)
  • Android开发参考
  • 求出e的值
  • CSP-S模拟24
  • 今年CSP...
  • 实用指南:VGG改进(9):融合Axial Attention的VGG16架构
  • 0voice-2.1.1-io多路复用select/poll/epoll
  • Transformer与ViT
  • comfUI背后的技术——VAE - 实践