java 多线程处理_java - 线程 - 多线程处理

本文介绍了如何使用Java的synchronized关键字实现线程锁,防止多线程并发问题。通过一个生产消费者模型展示了线程同步的重要性,其中包含wait(), notify()和notifyAll()的使用,以及如何防止假死状态。" 133060453,19673915,南方电网贵定供电局:无人机巡检系统与自动化实践,"['自动化', '无人机', '运维', '编程', '电力系统']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在基础中使用了java自带的Vector线程安全处理多线程。

这次试试用锁来进行处理

线程锁:

synchronized

使用synchronized修饰方法,这样调用这个方法的时候,这个方法会被锁定,只有当前对象使用完后才能释放让其他对象使用。

不加这个可能会多个对象同时访问这个方法,导致出现线程问题(比如出货方法,A运行到这个方法的判断是否还有货物,判断还有货物,B这时刚好也运行方法拿走了货物,A开始拿货就会报错)

public synchronized void 方法名(){...}

或者

synchronized (需要锁定的对象){ ... } 执行完代码后解锁

线程控制:

wait:

Object.wait() 让执行这个Object的线程进入等待状态,直到cpu再次分配资源(只要线程不消亡或者报错,cpu有空的时候还会自动分配资源给它执行),注意这里操作的对象是线程,多个单线程操作同一个对象,其中一个线程进入等待不影响其它线程操作这个对象。

如果在某个方法中写this.wait(); 进入等待状态的是当前操作这个对象的线程,不是当前class的对象。比如A调用了B中方法,这个方法有个this.wait(),执行到那里这个线程会断掉(不再继续往下执行),等待唤醒再继续。不影响C去调用B的方法。

所有线程都进入wait() ---》 假死状态。

防止假死需要找时机对线程进行唤醒(notify,notifyAll)

sleep:

Thread.sleep(等待时间毫秒)。 让调用方法的对象进入等待状态,等待时间到了自动醒来。

Object.notify:

唤醒当前对象的其中一个线程(cpu决定优先级,或者提前用 object.setPriority(int 优先级) 设置优先级,优先级为1-10, 10最高)

Object.notifyAll:

唤醒对象的所有线程。

生产消费者模型:

有人往仓库放,有人从仓库拿,多人同时操作同一个仓库。

主函数

packagemulti_thread;public classMultiThreadTest {public static voidmain(String[] args) {

Customer c1= new Customer("消费者1");

Customer c2= new Customer("消费者2");

Customer c3= new Customer("消费者3");

Customer c4= new Customer("消费者4");

Productor p1= new Productor("生产者1");

Productor p2= new Productor("生产者2");//生产者优先级高一些,先生产再消费

p1.setPriority(10);

p2.setPriority(10);//初始10个产品,有4个消费者每人买20次,2个生产者每人生产25个,也就是说至少会有20次买不到(消费速度 > 生产速度,还没来得及生产出来也可能买不到)

c1.start();

c2.start();

c3.start();

c4.start();

p1.start();

p2.start();

}

}

消费者

packagemulti_thread;public class Customer extends Thread{ //消费者,买取货物

privateString name;publicCustomer(String name){this.name =name;

}public voidrun(){for(int i = 0; i < 20; i++) { //假设每个消费者需要20个产品

buyGood();

}

}private voidbuyGood(){

Goods g=Goods.getInstance();

String s=g.removeGood();//多线程锁的另一种写法,在一段代码外面添加synchronized(上锁的对象){}//这样可以达到和方法上锁一样的效果//synchronized(g) {//s = g.removeGood();//}

if(s != null){

System.out.println(name+ "买走了" +s);

}else{

System.out.println(name+ "发现没货啦!");//try {//this.sleep(500);//当前Customer对象等0.1秒再买//System.out.println(name + "又开始买东西了!");//} catch (InterruptedException e) {//e.printStackTrace();//}//让某个Thread 对象(c1继承了Thread)等待111毫秒后自动醒来

}

}

}

生产者

packagemulti_thread;public class Productor extends Thread{ //生产者,增加货物

privateString name;publicProductor(String name){this.name =name;

}public voidrun(){for(int i = 0; i < 30; i++) { //假设每个生产者生产30个产品停止,刚好满足消费

productGood();

}

}private voidproductGood(){

Goods g=Goods.getInstance();

String s=g.addGood();

System.out.println(name+ "生产了" +s);

}

}

货物仓库

packagemulti_thread;importjava.util.ArrayList;public class Goods { //货物仓库,这次用String表示货物

private int num = 1; //用来区分货物

private static Goods goods = newGoods();private ArrayList goodList = new ArrayList<>(); //用String代表货物,懒得创建一个新类了。。。

{for(int i = 0; i < 20; i++){

addGood();

}

}//块,在构造方法之前自动运行,初始添加20个货物

privateGoods(){

}public staticGoods getInstance(){returngoods;

}//生产一个货物

public synchronized String addGood(){ //使用synchronized锁定方法,这样调用这个方法的时候,Goods对象会被锁定,执行完后才能释放。

goodList.add("货物" +num);

num++;return "货物" + num;//返回生产的货物名字

}//消费一个货物

public synchronizedString removeGood(){if(goodList.size() > 0) {

String s= goodList.remove(0);return s;//返回消费的货物名字;

}else{try{//wait的不是货物的线程,而是当前执行这个方法的对象所在线程(只有消费者调用这个方法)

System.out.println("有人发现到货物" + num + "的时候没货啦,等在那里不动啦");//没有添加this.notifyAll();的情况下://发现这句话运行了4遍后,4个消费者都没再买东西(因为消费者消费速度 > 生产者生产速度,还没来得及生产就卖完了),只有2个生产者还在生产。//程序卡在这里不再继续执行,称为:假死状态。//为了防止假死,在这个线程进入等待状态时,唤醒其他线程。//

//notify

this.notifyAll(); //----加上这句后,线程可以正常运行完毕。某个消费者发现没货后,过段时间还会再次尝试过购买(其他消费者发现没货了让他醒了)

this.wait();

}catch(Exception e) {

e.printStackTrace();

}return null;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值