You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java17使用@jdk.internal.vm.annotation.Contended报错如何解决

问题现象

在Java 17环境下使用@jdk.internal.vm.annotation.Contended注解开发伪共享测试代码时,两个主流IDE均出现报错:

  • Eclipse 提示:The type jdk.internal.vm.annotation.Contended is not accessible,运行时抛出编译异常:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
jdk.internal.vm.annotation cannot be resolved to a type

at falseSharingExample.ContendedExample1.<init>(ContendedExample1.java:5)
at falseSharingExample.FalseSharingMain.main(FalseSharingMain.java:7)
  • IntelliJ IDEA 编译时提示:

java: exporting a package from system module java.base is not allowed with --release

相关报错截图:
IDE报错截图

测试代码如下:

public class ContendedExample1 {

  @jdk.internal.vm.annotation.Contended 
  public volatile long count1 = 0;

  public volatile long count2 = 0;

}

public class FalseSharingMain {

  public static void main(String[] args) {
    
    ContendedExample1 obj1 = new ContendedExample1();
    
    long iteration = 1_000_000_000;
    
    new Thread(() -> {
        long sTime = System.currentTimeMillis();
        for(long i = 0; i < iteration; i++) {
            obj1.count1++;
        }
        long eTime = System.currentTimeMillis();
        System.out.println(eTime - sTime);
    }).start();
    
    new Thread(() -> {
        long sTime = System.currentTimeMillis();
        for(long i = 0; i < iteration; i++) {
            obj1.count2++;
        }
        long eTime = System.currentTimeMillis();
        System.out.println(eTime - sTime);
    }).start();
  }
}
问题原因

jdk.internal.vm.annotation.Contended是JDK内部专用注解,不属于公开支持的API范畴。从Java 9引入模块化系统后,该注解所在的jdk.internal.vm.annotation包被java.base模块封装,默认不对外开放访问权限。同时IDE默认启用的--release编译参数会严格校验模块访问规则,禁止应用代码直接引用系统模块的内部包。
另外需要注意:即使编译通过,JVM默认会限制@Contended注解的生效,需要额外添加参数开启注解处理,否则注解不会起到缓存行隔离的作用。

解决方法

方案1:配置IDE和JVM参数,允许使用内部注解

Eclipse 配置步骤

  • 右键项目选择「Properties」,进入「Java Build Path > Libraries」标签页
  • 展开当前绑定的JRE 17节点,双击「Access rules」选项
  • 点击「Add」,规则类型选择「Accessible」,规则模式填写jdk/internal/vm/annotation/**,保存规则配置
  • 进入「Java Compiler」配置页,取消勾选「Use '--release' option from compiler compliance」选项,关闭--release编译校验
  • 打开主类的运行配置,在VM arguments栏添加以下参数:
    --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED -XX:-RestrictContended
    

IntelliJ IDEA 配置步骤

  • 进入「File > Settings > Build, Execution, Deployment > Compiler > Java Compiler」配置页
  • 在「Additional command line parameters」输入框中添加:
    --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED
    
  • 进入「Project Structure > Project」配置页,将Project SDK、Project language level直接设置为Java 17,不要通过--release参数指定版本,避免触发模块导出限制
  • 打开主类的运行配置,在VM options栏添加以下参数:
    --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED -XX:-RestrictContended
    

方案2(推荐):手动实现缓存行填充,不依赖内部API

@Contended注解的核心作用是给标注的字段前后添加填充字节,避免同一缓存行被多个核心同时读写导致伪共享。可以直接手动在字段前后添加long类型占位变量实现相同效果,不需要修改任何编译、运行参数,兼容性更强:

public class ContendedExample1 {
    // 前置填充:7个long共56字节,加上对象头8字节刚好凑满64字节缓存行
    protected long p1, p2, p3, p4, p5, p6, p7;
    public volatile long count1 = 0;
    // 后置填充:7个long共56字节,隔离后续字段
    protected long p9, p10, p11, p12, p13, p14, p15;

    public volatile long count2 = 0;
}

内容的提问来源于stack exchange,提问作者Kavishka Madhushan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:45:35