java并发测试,java 多线程压测_java多线程Jmeter压测实现

 2023-09-22 阅读 23 评论 0

摘要:笔者最近在看jmeter源码,对多线程处理部分的了解记录如下。Part1线程与多线程概念提到线程先来看一下进程(线程的容器)的概念,进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活

笔者最近在看jmeter源码,对多线程处理部分的了解记录如下。

Part1 线程与多线程概念

提到线程先来看一下进程(线程的容器)的概念,进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。它可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体。它不只是程序的代码,还包括当前的活动,通过程序计数器的值和处理寄存器的内容来表示。

对于jmeter来说,运行中的jmeter程序实例便是一个进程。而该进程中会包含大量线程。

线程是程序执行流的最小单位,是一组命令的集合。在jmeter中一个线程可以用来执行一个测试用例。在起停等基本属性设置的基础上,线程运行时会根据testtree解析出的sample取样器按需执行流程中包含的测试请求。

java并发测试,不同的资料中对线程状态有不完全相同的描述,基本上分为五种状态:新建 开始(等待) 运行 挂起 和 停止。

在jmeter/压测宝中,需要有高并发性,大量的线程并行执行,其中每个线程代表一个VU。这就涉及到多线程的概念。

对于多线程,在java中有两种实现方式,即,一种是通过继承thread类;另一种是实现Runnable接口。由于java单继承机制,继承thread实现有更多的局限性,一般采用Runnable接口方式。同时,实现了Runnable接口的类,可以通过thread类构造方法public Thread(Runnable target) 来转化运行。

Jmeter中线程的实现也是采用了Runnable接口方式。

并发大量线程执行相同任务,需要统一管理配置多线程的状态,便需要引入线程组(threadgroup)的概念。

java创建线程,1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。>

Part2:线程组

Java中有threadgroup的概念,ThreadGroup是一个类,它的目的是提供关于线程组的信息。ThreadGroup API比较薄弱,它并没有比Thread提供了更多的功能。它有两个主要的功能:一是获取线程组中处于活跃状态线程的列表;二是为线程设置捕获异常处理器。

而这薄弱的API不能满足JMeter的需求,所以JMeter是自定义的threadgroup类。用来实现对一组线程(也就是一个测试实例的并发线程)的管理。它针对线程组的各项属性,如线程的延时启动时间/开始时间/结束时间/线程总数/正在运行的线程数/线程启动时间间隔进行设置。当有线程延时启动时,先创建等量守护线程,由守护线程根据时间创建对应的用户线程并依次启动;没有延时启动时,直接创建用户线程并依次启动。

java 多线程编程。另外,线程组提供scheduleThread(This will schedule the time for the JMeterThread.),对线程启动进行时间安排;并能够控制线程的相关方法:启动 暂停 停止 等待停止线程, 获取活动的线程数等。

上面提到,实现runnable接口的方式适合多个相同的程序代码的线程去处理同一个资源。多线程共享资源便容易引起线程安全问题。

Part3:线程安全

线程安全问题产生原理:

线程的工作原理,jvm有一个main   memory,而每个线程有自己的working   memory,一个线程对一个variable进行操作时,都要在自己的working   memory里面建立一个copy,操作完之后再写入main   memory。多个线程同时操作同一个variable,就可能会出现不可预知的结果。

比如,两个线程同时为一个数组添加项,当前数组长度为0.两个线程同时对其操作,会分别在自己的工作内存中拷贝一份进行添加。两线程分别添加完返回,此时数组长度已经是2,但是每个线程返回的数组长度依然是1,这就引发了问题。

java多线程实现。Jmeter中保证线程安全的方式:

一)在start方法执行之前定义好线程内部的变量;

Eg :

启动时间 终止时间等参数是通过第一种赋值,如下jmeter源码描述:

The following variables are set by StandardJMeterEngine.

This is done before start() is called, so the values will be published tothe thread safely

java多线程压测?线程的变量是在start方法执行之前,这样保证变量的作用范围仅限于线程内。

二)用volatile关键字来标识线程共用的变量(PS:当我们使用volatile关键字去修饰变量的时候,所以线程都会直接读取该变量并且不缓存它);

Eg:

线程共享的变量如running /onErrorStopTest等是采用volatile关键字。

三)通过synchronized同步代码块或方法体(PS:用synchronized的关键是建立一个monitor,这个monitor可以是要修改的variable也可以其他你认为合适的object比如method,然后通过给这个monitor加锁来实现线程安全,每个线程在获得这个锁之后,要执行完  从mainmemory  load到workingmemory   ->   use&assign   ->   store到mainmemory   的过程,才会释放它得到的锁。这样就实现了所谓的线程安全。);

Eg:

java 线程池?对于方法/代码块,如 static synchronized void incrNumberOfThreads()新增活动线程方法等,多线程共用的代码,需要用synchronized 进行同步。

笔者对多线程了解尚浅,文中不当之处敬请指正,万分感谢!

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/86414.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息