参考文档: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();
}
}