线程之同步通信

本文详细介绍了线程间同步通信的基本原理与实现方法,通过生产者消费者模型演示了如何使用wait(), notify() 和 notifyAll() 方法来避免死锁,确保线程间的正确交互。

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

线程之同步通信

所谓线程之同步通信,为了避免死锁,让线程在进入堵塞状态时尽量释放其锁定的资源,以为其他的线程提供运行的机会;

线程间的通信:

两个或两个以上的线程处理同一个资源,处理的动作是不一样的。

这样就需要将不同的动作代码放到不同的run方法中,run方法要封装到单独的类中。

同步中使用:

wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。

notify():唤醒等待的线程,唤醒第一个

notifyAll():唤醒所以等待的线程。

//资源类

classRes{

Stringname;

Stringsex;

booleanb;

}

//生产者类

classInputimplementsRunnable{

privateResr;

publicInput(Resr){

this.r=r;

}

@Override

publicvoidrun(){

intx=0;

while(true){

synchronized(r){

//判断是否需要生产

if(r.b)

try{

r.wait();//释放cpu资源,同时释放锁

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

if(x==0){

r.name="张三";

r.sex="男";

}else{

r.name="lisi";

r.sex="nv";

}

r.b=true;

r.notify();

}

x=(x+1)%2;

}

}

}

//消费者类

classOutputimplementsRunnable{

privateResr;

publicOutput(Resr){

this.r=r;

}

@Override

publicvoidrun(){

while(true){

synchronized(r){

if(!r.b)

try{

r.wait();//释放cpu资源,同时释放锁

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

System.out.println(r.name+"...."+r.sex);

r.b=false;

r.notify();

}

}

}

}

publicclassThreadDemo4{

/**

*@paramargs

*/

publicstaticvoidmain(String[]args){

Resr=newRes();

Inputin=newInput(r);

Outputout=newOutput(r);

Threadt1=newThread(in);

Threadt2=newThread(out);

t1.start();

t2.start();

}

}

或者

packagecom.csdn;

publicclassThreadDemo5{

/**

*@paramargs

*/

publicstaticvoidmain(String[]args){

//TODOAuto-generatedmethodstub

Res1r=newRes1();

Input1in=newInput1(r);

Output1out=newOutput1(r);

Threadt1=newThread(in);

Threadt2=newThread(out);

t1.start();

t2.start();

}

}

classRes1{

privateStringname;

privateStringsex;

privatebooleanb;

publicsynchronizedvoidset(Stringname,Stringsex){

if(b){

try{

wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

this.name=name;

this.sex=sex;

b=true;

notify();

}

publicsynchronizedvoidout(){

if(!b){

try{

wait();

}catch(InterruptedExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

System.out.println(name+"......"+sex);

b=false;

notify();

}

}

classInput1implementsRunnable{

privateRes1r;

publicInput1(Res1r){

this.r=r;

}

@Override

publicvoidrun(){

ints=0;

//TODOAuto-generatedmethodstub

while(true){

if(s==0){

r.set("小羊","男");

}else{

r.set("小猪","女");

}

s=(s+1)%2;

}

}

}

classOutput1implementsRunnable{

privateRes1r;

publicOutput1(Res1r){

this.r=r;

}

@Override

publicvoidrun(){

//TODOAuto-generatedmethodstub

while(true){

r.out();

}

}

}

这两个运行出来的结果是一样的,不过我比较喜欢第二种,可能是更具体,更简单,不像第一种那么复杂,把同步封装在资源里,然后底下直接调用即可;

wait():被锁定的对象可以调用wait()方法,这将导致当前线程被阻塞并释放该对象的互斥锁,即解除了wait()方法当前对象的锁定状态,其他的线程就有机会访问该对象。

notify():唤醒调用wait()方法后被阻塞的线程。每次运行该方法只能唤醒一个线程。

notifyAll():唤醒所有调用wait()方法被阻塞的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值