老卫带你学—java多线程和python多线程
Java多线程
Java多线程的生命周期及五种基本状态 如图所示:
这里写图片描述
线程的状态:
新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
java线程方式
3中方式:
继承Thread,实现Runnable,实现Callpble接口和FutureTask结合
线程操作波及到的方法
start()线程对象
join() 进入线程
wait() 等待状态
notify() 唤醒(1个)
notifyall() 唤醒(多个)
import java.util.ArrayList;//导入包
import java.util.List;//导入包
public class Text
{
static class ManTou{
private int num; //声明馒头
public ManTou(int num) {
this.num = num;
}
@Override
public String toString() {
return "第"+num+"个"; //输出第几个馒头
}
}
public static List<ManTou> manTous=new ArrayList<>(); //创建馒头的集合
public static void main(String[] args) { //为火夫和吃货赋值
new HuoFu("大头和尚").start(); //火夫赋值
new ChiHuo("白眉和尚").start(); //吃货赋值
new ChiHuo("牛逼和尚").start(); //吃货赋值
new ChiHuo("花和尚").start(); //吃货赋值
}
//火夫
static class HuoFu extends Thread{
private String name; //火夫的名字
public HuoFu(String name) {
this.name = name;
}
@Override
public void run() { //火夫执行蒸馒头的方法
try {
Thread.sleep(1000); //都先等待一会
} catch (InterruptedException e) { //异常处理
e.printStackTrace();
}
while (true) { //while判断
synchronized ("a") { //a的线程
System.out.println(name + "开始蒸馒头"); //输出火夫开始蒸馒头
for (int i = 0; i < 30; i++) { //判断馒头数量小于30个
manTous.add(new ManTou(i + 1)); //现有馒头+1
System.out.println("做完第" + (i + 1) + "个码 头");//输出做好第几个
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("馒头做好了,开始吃吧"); //做好馒头小于30 开始叫醒 其他人
"a".notifyAll(); // 叫醒所有人 (notifyAll()是叫醒a线程中所有人,如果只有一个人可以用notify())
}
synchronized ("b") { //b线程
try {
System.out.println("我先去睡一会,没了叫我"); //火夫输出我先去睡一会,没了叫我
"b".wait(); //让B(火夫)的线程进入等待状态
System.out.println("我知道了开始做去"); //如果有人唤醒则可以开始执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//吃货
static class ChiHuo extends Thread{
private String name; //声明名字
public ChiHuo(String name) {
this.name = name;
}
@Override
public void run() { //执行的方法体
synchronized ("a"){ //a的线程
try {
"a".wait(); //让a的线程进入等待状态
} catch (InterruptedException e) { //异常处理
e.printStackTrace();
}
}
ManTou m=null; //馒头是否为空
while (true) { //判断
synchronized ("a") {
System.out.println(name + "开始吃馒头"); //吃货开始吃
if (manTous.size() != 0) { /判断馒头个数是否为空
m = manTous.remove(0);
} else {
System.out.println(name + "发现没有馒头,叫醒火夫做馒头"); //如果没有馒头叫醒火夫
synchronized ("b"){
"b".notify(); //唤醒b的线程
}
try {
System.out.println("我等着呢,完事后叫我吃"); //交醒火夫之后告诉他 造好了叫我
"a".wait(); //使a的线程 进入等待状态
} catch (InterruptedException e) { //异常处理
e.printStackTrace();
}
}
}
if (m != null) { //判断馒头否是否为空
System.out.println(name + "消化馒头"+m.toString()); //吃到第几个了
int rd = (int) (Math.random() * 2000 + 1000); //消化馒头的时间(防止一直是同一个人吃)
m = null;
try { //异常处理
Thread.sleep(rd);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
Python的多线程
线程实现方式
两种方式:类 函数
线程操作涉及到的方法
对象
Thread:start启动 join加入新线程
Lock、Rlock:acquire枷锁 release释放锁
Condition:acquire枷锁 release释放锁 wait notify notify_all()
Event:set:等同于notifyAll clear 取消notifyAll
time:sleep
timer:Timer(interval, function, args=[], kwargs={})
interval: 指定的时间
function: 要执行的方法
args/kwargs: 方法的参数
import threading //用import倒入模块
import time //用import倒入模块
mantous=[] //馒头的列表
a=threading.Lock() //a线程
b=threading.Lock() //b线程
ca=threading.Condition(a) //ac控制时间a
cb=threading.Condition(b) //cb控制时间b
#火夫的任务函数
def huofu(name): //火夫的名字
time.sleep(1) //所有的进入等待
while True: //while 判断
ca.acquire() //获取ca的枷锁
for i in range(1,31): //30个
mantous.append("第{0}个馒头".format(i)) //第多少个
print("做好第{0}个馒头".format(i)) //火夫做好几个
time.sleep(0.1) //没做一个休息级的时间
print("馒头做好,叫醒吃货") //如果 while完 开始唤醒
ca.notify_all() //ca唤醒
ca.release() //ca释放锁,开启下一个线程
print("{0}去等待".format(name)) //火夫就开始等待
cb.acquire() //获取cb的枷锁
cb.wait() //cb的线程进入等待状态
cb.release() //cb释放锁,开启下一个线程
#吃货的任务函数
def chihuo(name): //吃货名字
ca.acquire() //获取ca的枷锁
ca.wait() //ca进入等待状态
ca.release() //有人唤醒ca开锁
while True: //判断
m=None
ca.acquire() //获取ca的枷锁
if len(mantous) != 0 : //判断馒头是否为0-
m=mantous.pop() //吃馒头
else:
print("没馒头了")
cb.acquire() //获取cb的枷锁
cb.notify() //唤醒cb
cb.release() //cb释放锁,开启下一个线程
ca.wait() //ca进入等待状态
ca.release() //ca 释放锁,开启下一个线程
if m is not None:
print("{0}吃{1}".format(name,m)) //赋值谁吃第几个
time.sleep(1)//吃完休息一下
threading._start_new_thread(huofu,('大头和尚',)) //创建线程为火夫name赋值
threading._start_new_thread(chihuo,('百媚和尚',))//创建线程为吃货name赋值
threading._start_new_thread(chihuo,('牛鼻子和尚',))//创建线程为吃货name赋值
threading._start_new_thread(chihuo,('花和尚和尚',))//创建线程为吃货name赋值
input()