JVM整理笔记之测试工具JCStress的使用及其注解的应用

JCStress是OpenJDK提供的一个高并发测试工具,用于研究JVM、类库及硬件在并发条件下的行为。文章介绍了如何使用maven集成JCStress,通过编写测试代码展示了volatile关键字在多线程环境中的指令重排序问题,并解释了JCStress的注解如@JCStressTest、@State、@Outcome和@Actor的用途。同时,文章对比了JCStress与jmeter在测试上的区别,强调JCStress更专注于并发代码的细粒度分析。
摘要由CSDN通过智能技术生成

前言

如果要研究高并发,一般会借助高并发工具来进行测试。JCStress(Java Concurrency Stress)它是OpenJDK中的一个高并发测试工具,它可以帮助我们研究在高并发场景下JVM,类库以及硬件等状况。

如何使用JCStress

此演示需要使用到maven工程,首先需要引入jar包,核心包是必须要的,样例包是非必须的。

<dependencies>
    <!-- jcstress 核心包 -->
    <dependency>
        <groupId>org.openjdk.jcstress</groupId>
        <artifactId>jcstress-core</artifactId>
        <version>0.3</version>
    </dependency>
    <!-- jcstress测试用例包 -->
    <dependency>
        <groupId>org.openjdk.jcstress</groupId>
        <artifactId>jcstress-samples</artifactId>
        <version>0.3</version>
    </dependency>
</dependencies>

  • 目的:在学习JVM是,对于volital我们知道线程操作静态变量的时候,容易发生指令重排序,因此写一个指令重排序的测试代码,来看看究竟。

测试代码

@org.openjdk.jcstress.annotations.JCStressTest
@Outcome(id = {"0"},expect = Expect.ACCEPTABLE_INTERESTING , desc = "wrong result")
@Outcome(id = {"-1","5"},expect = Expect.ACCEPTABLE,desc = "normal result")
@State
public class JCStressTest {
    private boolean flag;
    private int x;

 public JCStressTest(){};
@Actor
 public void actor1(I_Result r){
     if(flag){
         r.r1 = x;
     }else{
         r.r1 = -1;
     }
 }
 @Actor
 public void actor2(I_Result r){
     this.x = 5;
     flag = true;
 }
}

配置程序的主类,org.openjdk.jcstress.Main是JCStress自带的一个启动类;然后可以配置-t参数设置需要测试的类,当然 -t 后面也可以指定包名,表示执行指定包下的所有测试类。如果不指定-t参数,默认会扫描项目下所有包的类。
在这里插入图片描述

运行程序- 先mvn clean install 在执行java -jar …,结果显示,x的值出现了0,-1,5三种结果,其中值为0不是我期待的,但是它在高并发下确实出现了,虽然相比其他值(几十万次)出现的概率(200多次)很低。

在这里插入图片描述
有些人会说用jmeter工具不也可以测试高并发,但是它们的侧重点还是不一样的,jmeter侧重对于接口整体的响应速度等进行测试,而JCStress框架能对某块逻辑代码进行高并发测试,更加侧重JVM,类库等领域的研究

而且,JCStress会考虑不同JVM参数设置下的测试,而且自动帮我们设置,例如上图所示[-XX:-TieredCompilation]。

除了命令行窗口显示的测试结果之外,还会在项目所在的目录下生成 results文件夹,生成测试结果文档,其中index.html是测试总览,其他html文件是每个测试类的报告,结合结果数据结构可视化图形更加容易理解。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

JCStress 注解说明

@JCStressTest

标记一个类为并发测试的类,它有一个org.openjdk.jcstress.annotations.Mode枚举类型的属性value。Mode.Continuous模式表示会运行几个Actor,Ariter线程,并收集统计结果。Mode.Termination模式代表运行具有阻塞/循环操作的单个Actor,看是否响应Singal信号。

@State

标记一个类是有状态的,即拥有可以读写的数据,例如上例的x和falg。State类只能是public的,不能是内部类(可以是静态内部类),并且得有一个默认构造方法。

@Outcome

描述测试的结果,它有3个属性,id属性为一个字符串数组,表示接收的结果,支持正则表达式;expect表示对观测结果的期望,它的值是一个枚举值;desc属性指定一个易于人类理解的对结果的描述。@Outcomes注解可以组合多个结果注解。

@Actor

@Actor是一个中心测试注解,它标记的方法会被一个特定的线程调用,每一个对象的方法只能被调用一次。多个Actro方法调用顺序是不保证的,它们是并发执行的,方法可以抛出异常并且会导致测试失败。Actor方法所在的类必须有State或者Result注解。

@Arbiter

它的作用其实和@Actor差不多,但是Arbiter标记的方法调用是在所有@Actor标记的方法调用之后,所以它标记的方法一般作为收集最后的结果来使用。

@Signal

此注解也是标记方法的,但是它是在JCStressTest的Termination模式下工作的,它的调用是在所有Actor之后。

@Result

它标记的类被作为测试结果的类,JCStress自带的org.openjdk.jcstress.infra.results包下就有大量的测试结果类,不同的类可以用来保持不同的结果。例如I_Result类有一个int类型的变量r1;II_Result类有2个int类型的变量r1和r2。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李知恩真爱粉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值