python(java)线程对比+线程的传参

参考文档:python 线程创建和传参(28)

https://www.cnblogs.com/songyunjie/p/16829593.html

变量 数据类型 列表[增删改查] if语句 while语句 for语句 字典[Map 增删改查] 函数 类 对象 文件 异常  线程

1.一个进程资源包含多个线程

#一个进程资源包含多个线程
## 导入线程threading模块
from threading import Thread
from multiprocessing import Process
import os,time,random

def func(num):
    time.sleep(random.uniform(0, 1));
    print("当前进程{},参数是{}".format(os.getpid(), num));

for i in range(10):
    # 创建并初始化线程,返回线程句柄
    #t = threading.Thread(target=函数名)
    t=Thread(target=func,args=(i,))
    t.start()

print(os.getpid())


100248
当前进程100248,参数是7
当前进程100248,参数是6
当前进程100248,参数是2
当前进程100248,参数是8

java

import java.lang.management.ManagementFactory;

public class TestMainThread  extends Thread{
    private String name;
    private  String pid;
    public TestMainThread(String name,String pid) {
        this.name = name;
        this.pid = pid;
    }
    @Override
    public void run(){
        //https://www.jeremysong.cn/cn/how-to-get-java-pid/
        System.out.println("Pid is:" + pid+" hello " + name);
    }
    public static void main(String[] args) {
        String name = ManagementFactory.getRuntimeMXBean().getName();
        System.out.println(name);

        String pid = name.split("@")[0];
        for (int i = 0; i <3;i++ ) {
            TestMainThread thread = new TestMainThread("world-"+i,pid);
            thread.start();
        }
        System.out.println("-------下一个问题是如何让线程运行完才执行主线程----------");
    }
}

80192@DESKTOP-QI8G6SM
-------下一个问题是如何让线程运行完才执行主线程----------
Pid is:80192 hello world-0
Pid is:80192 hello world-1
Pid is:80192 hello world-2

2.线程的传参方式

threading.Thread()函数中有两个缺省参数 args 和 kwargs ,args 是元组类型,kwargs 是字典类型,缺省值默认为空,除此之外,其实还可以设置线程的名字等,其函数声明如下:

#给子线程执行单元传递参数
# 导入线程threading模块
import threading
import  time
def sing(a,b,c):
    print("--a{},--b{},--c{}",a,b,c);
    for i in range(5):
        print("子线程{}执行",i);
        time.sleep(0.5);


#1.使用args传递参数: 元素形式传递位置参数
# 创建并初始化线程,返回线程句柄
t1 = threading.Thread(target=sing,args=(1,2,"test1"),name='test1');
t1.start();
print("-------t1 end--------")
#2.使用kwargs传递关键字参数
t2 = threading.Thread(target=sing,kwargs={'a':1,'b':2,'c':"test2"},name='test2');
t2.start();
print("-------t2 end--------")
#3.同时使用args和kwargs传递参数
t3 = threading.Thread(target=sing,args=(1,),kwargs={'b':2,'c':"test3"},name='test3')
t3.start();
print("-------t3 end--------")
















# 导入线程threading模块
import threading
# 导入内置模块time
import time
 
def wash_clothes(*args,**kargcs):
    print("wash_clothes:",args)
    print("wash_clothes:", kargcs)
 
def clean_room(*args,**kargcs):
    print("clean_room:",args)
    print("clean_room:", kargcs)
 
if __name__ == "__main__":
 
    t1 = threading.Thread(target=wash_clothes,
                          args=(1,"猿说python"),   # args 传递元组,可以同时传递多个数据
                          kwargs={"a":1,"b":False}) # kwargs 传递字典,可以同时传递多个键值对
 
    t2 = threading.Thread(target=clean_room,
                          args=(2,False), # args 传递元组,可以同时传递多个数据
                          kwargs={"c":0.2,"d":False}) # kwargs 传递字典,可以同时传递多个键值对
 
    t1.start()
    t2.start()




相关函数的介绍

1.threading.Thread() — 创建线程并初始化线程,可以为线程传递参数 ;

2.threading.enumerate() — 返回一个包含正在运行的线程的list;

3.threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果;

4.Thread.start() — 启动线程 ;

5.Thread.join() — 阻塞函数,一直等到线程结束为止 ;

6.Thread.isAlive() — 返回线程是否活动的;

7.Thread.getName() — 返回线程名;

8.Thread.setName() — 设置线程名;

9.Thread.setDaemon() — 设置为后台线程,这里默认是False,设置为True之后则主线程不会再等待子线程结束才结束,而是主线程结束意味程序退出,子线程也立即结束,注意调用时必须设置在start()之前;

# 导入线程threading模块
import threading
# 导入内置模块time
import time
 
def wash_clothes(*args,**kargcs):
    time.sleep(2)
    print("wash_clothes:",args)
    time.sleep(2)
    print("wash_clothes:", kargcs)
 
def clean_room(*args,**kargcs):
    time.sleep(2)
    print("clean_room:",args)
    time.sleep(2)
    print("clean_room:", kargcs)
 
if __name__ == "__main__":
 
    t1 = threading.Thread(target=wash_clothes,
                          args=(1,"猿说python"),   # args 传递元组,可以同时传递多个数据
                          kwargs={"a":1,"b":False}) # kwargs 传递字典,可以同时传递多个键值对
 
    t2 = threading.Thread(target=clean_room,
                          args=(2,False), # args 传递元组,可以同时传递多个数据
                          kwargs={"c":0.2,"d":False}) # kwargs 传递字典,可以同时传递多个键值对
 
    # setDaemon(True)意味着主线程退出,不管子线程执行到哪一步,子线程自动结束
    # t1.setDaemon(True)
    # t2.setDaemon(True)
    t1.start()
    t2.start()
 
    print("threading.enumerate():",threading.enumerate())
    print("threading.activeCount():", threading.activeCount())
    print("t1.isAlive():",t1.isAlive())
    print("t1.getName():", t1.getName())
    print("t2.isAlive():", t2.isAlive())
    t2.setName("my_custom_thread_2")
    print("t2.getName():", t2.getName())

1.默认主线程会等待所有子线程结束之后才会结束,主线程结束意味着程序退出;如果setDaemon设置为True,主线程则不会等待子线程,主线程结束,子线程自动结束;

2.threading模块除了以上常用函数,还有互斥锁Lock/事件Event/信号量Condition/队列Queue等,

2.java多线程传递参数的方法


通过构造函数进行传递Thread

public class TestMainThread  extends Thread{
    private String name;
    private  String pid;
    public TestMainThread(String name,String pid) {
        this.name = name;
        this.pid = pid;
    }
    @Override
    public void run(){
        //https://www.jeremysong.cn/cn/how-to-get-java-pid/
        System.out.println("Pid is:" + pid+" hello " + name);
    }
    public static void main(String[] args) {
        String name = ManagementFactory.getRuntimeMXBean().getName();
        System.out.println(name);

        String pid = name.split("@")[0];
        for (int i = 0; i <3;i++ ) {
            TestMainThread thread = new TestMainThread("world-"+i,pid);
            thread.start();
        }
        System.out.println("-------下一个问题是如何让线程运行完才执行主线程----------");
    }
}


通过变量和方法传递数据Runnable

启动2个线程,每个线程处理100条数据

public class MyThread2 implements Runnable {
    private String name;
    public void setName(String name){
        this.name = name;
    }
    @Override
    public void run() {
        System.out.println("hello " + name);
    }
    //通过变量和方法传递数据
    public static void main(String[] args) {
        MyThread2 myThread = new MyThread2();
        myThread.setName("world");
        Thread thread = new Thread(myThread);
        thread.start();
    }
}

package org.jeecg.modules.gybmapi;

public class Printer implements Runnable {
    private String message;

    public Printer(String message) {
        this.message = message;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + "执行" + i +message);
        }
    }

}


通过回调函数传递数据

public class ThreadParam extends Thread {
    private Work work;
    ThreadParam(Work work){
        this.work=work;
    }

    @Override
    public void run() {
        Random random = new Random();
        Data data = new Data();
        int n1 = random.nextInt(1000);
        int n2 = random.nextInt(2000);
        int n3 = random.nextInt(3000);
        int[] tt = new int[]{n1,n2,n3};
        //使用回调函数
        work.process(data,tt);
        System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+"
                + String.valueOf(n3) + "=" + data.value);
    }

    public static void main(String[] args) {
        ThreadParam threadParam=new ThreadParam(new Work());
        threadParam.start();

    }
}



class Work{
    public void  process(Data data, int[] numbers){
        for (int n:numbers) {
            data.value += n;
        }
    }
}
class Data{
    int  value=0;
}

python线程的使用和理解

# 导入线程threading模块
import threading
# 导入内置模块time
import time

#函数 def +类 +对象
def eat():
    print("eat start");
    # sleep 5 秒,默认以秒为单位
    time.sleep(5);
    print("eat end");

def write():
    print("write io start");
    # sleep 5 秒,默认以秒为单位
    time.sleep(5);
    print("write io end");

if __name__ == '__main__':
    t1=threading.Thread(target=eat);
    t2=threading.Thread(target=write);
    t1.start();
    t2.start();

java

 public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("--eat start-----");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("--eat end-----");
        });
        Thread thread2 = new Thread(() -> {
            System.out.println("--write io start-----");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("--write io end-----");
        });
        thread.start();
        thread2.start();
    }

运行程序可以发现程序从运行开始到结束,一共耗时5秒时间!注意观察输出日志:

  • 第一步:eat开始和写开始几乎同时开始,两个事件同时执行.
  • 第二步:程序停止5秒;
  • 第三步:eat和写几乎同时完成

多线程可以同时运行多个任务,效率远比单线程更高!

运行程序可以发现程序从运行开始到结束,一共耗时10秒时间!注意观察输出日志:

  • 第一步:洗衣服开始;
  • 第二步:程序停止了5秒;
  • 第三步:洗衣服完成,打扫房间开始
  • 第四步:程序停止5秒;
  • 第五步:打扫房间结束,程序结束;

线程的顺序执行

import  unittest
import  threading

class  TestThreadExecution(unittest.TestCase):
        
        def  test_thread_execution_order(self):
                result_list  =  []
                
                def  add_to_list(number):
                        result_list.append(number)
                        
                thread1  =  threading.Thread(target=add_to_list,  args=(1,))
                thread2  =  threading.Thread(target=add_to_list,  args=(2,))
                thread3  =  threading.Thread(target=add_to_list,  args=(3,))
                
                #  Start  the  threads
                thread1.start()
                thread2.start()
                thread3.start()
                
                #  Wait  for  all  threads  to  finish
                thread1.join()
                thread2.join()
                thread3.join()
                
                #  Check  if  the  result  list  contains  the  numbers  added  in  order
                self.assertEqual(result_list,  [1,  2,  3])

if  __name__  ==  '__main__':
        unittest.main()
 Thread thread1 = new Thread(() -> {
            System.out.println("Thread 1");
        });
        Thread thread2 = new Thread(() -> {
            System.out.println("Thread 2");
        });
        Thread thread3 = new Thread(() -> {
            System.out.println("Thread 3");
        });
        thread1.start();
        thread1.join();
        thread2.start();
        thread2.join();
        thread3.start();
        thread3.join();



public class ThreadExecutionOrder {
    private static int sharedCount = 0;
    public static void main(String[] args) {
        Object lock = new Object(); // 定义一个共享的锁对象
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) { // 通过共享的锁对象来实现同步
                    while(sharedCount != 0) { // 如果前一个线程还未执行完,则等待
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Thread 1");
                    sharedCount = 1; // 修改共享变量的值,表示当前线程已经完成任务
                    lock.notifyAll(); // 唤醒其他等待线程
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    while(sharedCount != 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Thread 2");
                    sharedCount = 2;
                    lock.notifyAll();
                }
            }
        });

        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    while(sharedCount != 2) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Thread 3");
                    sharedCount = 3;
                    lock.notifyAll();
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();
    }
}

### 实现JMeter跨线程组参数传递的方法 在JMeter中,由于各线程组之间的独立性,直接实现跨线程组的参数传递并不简单。然而,通过一些特定的技术手段,可以完成这一目标。以下是几种常见的方法及其示例。 #### 方法一:使用`__setProperty()`和`${__P()}`函数 可以通过设置全局属性来共享变量。具体操作如下: 1. **在线程组A中设置全局属性** 使用JSR223 PostProcessor或BeanShell PostProcessor脚本将局部变量转换为全局属性。 ```groovy vars.put("localVar", "value"); // 设置本地变量 props.setProperty("globalVar", vars.get("localVar")); // 将本地变量转为全局属性 ``` 2. **在线程组B中读取全局属性** 利用 `${__P(globalVar)}` 函数或者 JSR223 PreProcessor 获取该全局属性值。 ```groovy String globalValue = props.getProperty("globalVar"); vars.put("sharedVar", globalValue); // 将全局属性赋给当前线程组的局部变量 ``` 这种方法适用于简单的字符串类型的参数传递[^1]。 --- #### 方法二:利用文件作为中间媒介 如果数据量较大或复杂度较高,可以选择将数据写入文件再由其他线程组读取。 1. **在线程组A中保存数据至文件** ```java import org.apache.commons.io.FileUtils; FileUtils.writeStringToFile(new File("data.txt"), "token=abc123", "UTF-8"); ``` 2. **在线程组B中从文件加载数据** ```java import java.nio.file.Files; import java.nio.file.Paths; String content = new String(Files.readAllBytes(Paths.get("data.txt")), "UTF-8"); vars.put("token", content.split("=")[1]); ``` 这种方式适合于需要持久化存储的情况[^4]。 --- #### 方法三:借助CSV Data Set Config组件 当多个线程组需要访问相同的数据源时,可统一配置一个 CSV 文件供它们共同读取。 1. 创建名为 `tokens.csv` 的文件并填充必要的 token 值: ``` token abc123 def456 ghi789 ``` 2. 配置两个线程组均指向同一个 CSV 数据集元件,并指定相同的路径与字段名。 此方案特别适合批量测试场景下重复使用的固定参数集合[^2]。 --- #### 方法四:采用Redis或其他外部缓存服务 对于分布式环境下的动态交互需求,则推荐引入 Redis 这样的内存数据库充当桥梁角色。 1. 在线程组 A 登录成功后立即将 Token 存储到 Redis 中; 2. 线程组 B 请求前先查询对应的 Key 来获取最新有效的认证凭证。 虽然稍微复杂些,但性能优越且扩展性强[^3]。 --- ```python import redis # Thread Group A - Store value into Redis r = redis.Redis(host='localhost', port=6379, db=0) r.set('auth_token', 'generatedToken') # Thread Group B - Retrieve value from Redis retrieved_value = r.get('auth_token').decode('utf-8') print(f"Retrieved Auth Token: {retrieved_value}") ``` --- ### 总结 以上介绍了四种主流方式用于解决 JMeter 跨线程组间参数交换的问题。实际应用过程中应依据项目具体情况灵活选用最合适的策略。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值