java 线程变量put_java-如何将变量从一个线程组传递给JM中的另一个

java-如何将变量从一个线程组传递给JM中的另一个

我有一个带有2个线程组的JMeter测试-第一个是一个线程(创建一些库存),第二个有多个线程(购买所有库存)。 我使用BeanShell断言和XPath提取程序来解析返回的值(即XML)并存储变量(例如要购买的商品的ID)。

但是,无论是提取到标准${jmeter}类型变量还是${__BeanShell(vars.get("jmeter"))}类型var中,在第一个线程组中创建的值在第二个线程组中均不可用。 无论如何,在第一个线程组中创建一个变量并使第二个线程组可见?

9个解决方案

68 votes

我无法使用变量执行此操作(因为这些变量在各个线程中都是局部的)。 但是,我可以通过属性解决此问题!

同样,我的第一个ThreadGroup完成了所有的设置,并且我需要该工作中的一些信息才能供第二个ThreadGroup中的每个线程使用。 我在第一个ThreadGroup中具有以下内容的BeanShell断言:

${__setProperty(storeid, ${storeid})};

$ {storeid}是使用XPath Extractor提取的。 BeanShell断言还执行其他操作,例如检查是否从上一次调用返回了storeid等。

无论如何,在第二个ThreadGroup中,我可以将Samplers中“ storeid”属性的值与以下内容一起使用:

${__property(storeid)}

奇迹般有效!

Todd R answered 2020-02-03T02:18:29Z

14 votes

根据JMeter文档:

16.12在线程和线程组之间共享变量

变量是线程本地的,无法读取一个线程中设置的变量   另一个。 这是设计使然。 对于可以确定的变量   在测试开始之前,请参阅参数化测试(上文)。 如果值   在测试开始之前未知,有多种选择:

将变量存储为属性-属性对于   JMeter实例

将变量写入文件并重新读取。

使用bsh.shared命名空间-请参见16.8.2共享变量

编写自己的Java类

在线程之间传递变量的另一种方法是使用jmeter-plugins,如下面的Andrey Botalov所述。

但是我发现第一次使用它有点令人困惑,但是它在线程之间传递时可以完全控制变量。按照我的示例使用BeanShell,您会发现它很简单:

fd27deedf0e3ae8179e39ae750429784.png接下来参考下面的图片部分:

(1.1)在这里,我在“用户定义的变量”中创建了自定义变量(或者您可以使用BSF Proccessor做到这一点-在此示例中已禁用(1.2))

(2.1)(2.4)我在第一个线程中成功使用了变量-没什么特别的:)

(2.2)添加了BeanShell PostProcessor并自定义了我的变量

(2.3)添加到队列

(3.1)在第二个线程中-从队列中获取变量-具有您想要的任何名称。 但是要小心,请明智地使用超时,因为此线程将一直等到之前完成,这样才能获取修改后的变量(具有较长响应的实验)

(3.2)(3.3)(3,4)重复了使用和修改变量的步骤

(3.5)变量在新队列中再次发送-因此为其提供新名称

(4.1)(4.2)(4.3)从新队列中抓取的已修改变量,例如charm

警告

如果添加更多线程,则向具有变量的线程组添加一些计数器,并将此变量名称添加至队列名称-在尝试捕获队列的线程组中执行相同的操作,这样队列将为每个线程具有唯一的名称(如果您写了注释, 需要更清晰的说明)

如果一个线程组中有多个HTTP请求,则将线程通信预处理器添加为最后一个(如果要实现某些自定义功能,则作为其他子代)HTTP请求

播放,修改,自定义以获得最佳结果:)添加更多线程可能会导致不良行为,因此您需要保持警惕。

66e908b89409fb63cfb58e88db3ec8a9.png

pbaranski answered 2020-02-03T02:20:24Z

10 votes

我发现我认为这是完成此工作的最简单方法。

采用

Bean Shell PostProcessor

设置变量([http://jmeter.apache.org/usermanual/best-practices.html#bsh_variables)]

import org.apache.jmeter.util.JMeterUtils;

JMeterUtils.setProperty("PC_CREATED_PROMO_CODE", "value");

或者,如果您正在读取变量

import org.apache.jmeter.util.JMeterUtils;

JMeterUtils.setProperty("PC_CREATED_PROMO_CODE", vars.get("Extracted_PC_CREATED_PROMO_CODE"));

然后从另一个线程组中,通过([http://jmeter.apache.org/usermanual/functions.html#__property)]进行读取

${__property(PC_CREATED_PROMO_CODE)}

Joviano Dias answered 2020-02-03T02:21:01Z

8 votes

为此,JMeter插件具有线程间通信。

有两种使用方法:

后处理器/预处理器

功能__fifoPut和__fifoPop

我认为PostProcessor / PreProcessor更易于使用。

Andrei Botalov answered 2020-02-03T02:21:39Z

4 votes

在JMeter中这是不可能的,因为这不是正常的客户端行为(线程之间的共享参数)。 而不是使用一个带有控制器的线程组:

Thread Group

+ Create inventory

+ + XPath

+ Loop

+ + Purchase inventory

Mork0075 answered 2020-02-03T02:21:59Z

4 votes

好吧,这是做到这一点的一种方法。 请按照以下步骤操作,它将起作用,以后您可以根据需要进行调整! 线程之间不共享变量(JMeter可能将此功能称为:))。 但是属性! 因此,将变量设置为属性,如下所示:

1)单击您的测试计划并启用“连续运行线程组”->这使线程组有序运行,而不是随机运行。 (您可以稍后对其进行调整,但现在使其开始工作。)

2)例如创建一个名为“ setup”的线程组; 在该线程组中,添加具有以下代码的BeanShell Sampler:

import org.apache.jmeter.util.JMeterUtils;

JMeterUtils.setProperty("theNameOfYourNewProperty", "theValueOfYourPropery");

所以现在属性已设置! 如果要存储为属性的值是allready变量(例如,用户定义的变量或reqex变量),则可以执行以下操作:

JMeterUtils.setProperty("theNameOfYourNewProperty", vars.get("theNameOfYourVariable"));

3)添加一个测试组“实际测试”,例如线程数大于1;    添加一个测试,并向该测试添加具有以下代码的BeanShell预处理器:

import org.apache.jmeter.util.JMeterUtils;

vars.put("theNameOfYourNewProperty", JMeterUtils.getProperty("theNameOfYourNewProperty"));

因此,现在您已经在该线程中创建了一个名为theNameOfYourNewProperty的变量,该变量具有系统属性theNameOfYourNewProperty的值。 在测试中,您现在可以像这样访问它:

${theNameOfYourNewProperty}

而且它将适用于每个线程,而不仅仅是第一个线程。

Fico answered 2020-02-03T02:22:47Z

1 votes

让我们重生一下:)在线程之间传输变量的另一种方法是写入/读取文件。 在线程之间传递变量

olyv answered 2020-02-03T02:23:07Z

1 votes

另一个解决方案是使用简单表服务器来管理数据集。此功能是添加的1.2 JMeter插件。

“主要思想是在JMeter插件中使用一个微型http服务器来管理数据集文件,并通过简单的命令来获取/添加文件中的数据行”

查看文档:[http://jmeter-plugins.org/wiki/HttpSimpleTableServer/]

问候。

Vincent Daburon answered 2020-02-03T02:23:40Z

0 votes

478945b8496acc02f8d6ae2746c910cd.png

只需添加一个bean shell断言,就可以使用属性函数将值分配给一个变量(例如全局变量),该变量即使在转到其他线程后也将保留该值。

线程组>>添加>>断言>> Bean Shell断言

${__setProperty(Global_variable_Name,${Variable_name_whose_Value_to_be_Passed})}

然后在另一个线程中,您可以调用此全局变量并可以使用它

以下是调用存储值所需的函数:

${__property(global_variable_name)}

[https://medium.com/@priyank.it/jmeter-passing-variables-between-threads-a4dc09903b59]

Vajjala Vinay Rao answered 2020-02-03T02:24:18Z

Java 线程之间的变量传递是一件比较复杂的事情,因为线程之间是相互独立的,每个线程都有自己的栈空间和变量存储空间。在多线程编程,我们经常需要在线程之间传递某些变量或者数据,这就需要使用一些特殊的技术来实现。 其一种技术就是使用 TransmittableThreadLocal(TTL),它可以让我们在多个线程之间传递变量,而且还可以保证变量的值在每个线程都是唯一的。 TTL 是一个线程局部变量的扩展,它可以让我们在一个线程创建一个变量,并且在任何一个线程都能够访问到这个变量的值。而且,当子线程结束时,TTL 会自动回收这个变量。 下面是一个使用 TTL 的示例代码: ``` import com.alibaba.ttl.TransmittableThreadLocal; public class Demo { private static TransmittableThreadLocal<String> threadLocal = new TransmittableThreadLocal<>(); public static void main(String[] args) { // 在主线程设置值 threadLocal.set("value set in main thread"); // 创建子线程并启动 Thread thread = new Thread(() -> { // 在子线程获取值 String value = threadLocal.get(); System.out.println("value in sub thread: " + value); }); thread.start(); } } ``` 在这个示例代码,我们首先创建了一个 TTL 对象 threadLocal,然后在主线程设置了一个值,接着创建了一个线程,并在子线程获取了这个值。当子线程结束时,TTL 会自动回收这个变量。 TTL 的原理比较简单,它使用了 Java 的 InheritableThreadLocal 来实现。当我们在主线程创建了一个 TTL 变量时,它会将这个变量存储到 InheritableThreadLocal 。当我们创建子线程时,子线程会继承主线程的 InheritableThreadLocal 对象,并且会在自己的线程空间创建一个新的 TTL 变量,这个变量的值会从主线程变量拷贝过来。当子线程结束时,TTL 会自动回收这个变量。 总的来说,TTL 是一个非常方便的工具,它可以让我们在多个线程之间传递变量,而且还能够保证变量的值在每个线程都是唯一的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值