20.线程间通讯(wait、notify应用)

 

线程间通讯(waitnotify应用)

 引言

线程间如何通讯?通讯的方式其实有好几种,其中有一种就是wait,notify方式,与此相关的,还有一个比较经典的例子,那就是生产者与消费者,生产者指的是生产者线程,消费者指的是消费者线程,生产者线程负责生产数据,消费者线程负责消费数据

数据还没生产的时候,消费者线程先等待,

 

 

 

 

 

 

与此同时生产者线程开始生产数据,

 

 

 

 

 

 

数据生产以后叫醒等待中的消费者线程起来消费数据,

随后生产者线程等待消费者线程开始消费数据,消费完数据以后,叫醒等待中的生产者线程起来生产数据。

 

 

 编写一个生产者与消费者的例子

如此繁复,下面来编写一个生产者与消费者的例子。

一共有三个步骤,第一步编写一个数据类,第二步编写一个生产者任务,第三步编写一个消费者任务。

 

 

 数据类

首先来编写一个数据类,定义一个描述数据的类data,在类中定义一个存放数据的属性message,随后定义一个获取数据的方法getmessage。再定义一个设置数据的方法。Setmessage。

 

 

 生产者

至此数据类编写完成,再来编写生产者任务,定义一个生产者任务类producer,在类里面定一个data类型的属性,它主要是用于传递数据,然后重载producer构造方法,用于初始化data,接着编写任务部分,定义一个计数器用于给数据编号,方便后面观察使用,while处无限生产数据,定义一个同步锁为data同步代码块,在同步代码块中先判断数据是否为空,当数据为空时开始生产数据,数据生产完以后打印出来,目的是为了和消费数据进行对比,

 

 

生产一个,消费一个,接着调用notify方法唤醒在锁上等待的单个线程。 


这里唤醒的是消费者线程,再接着使当前现场等待,也就是使生产者线程等待,等消费者线程消费数据,他消费完数据以后会唤醒生产者线程,最后使用try---catch方法抛出的异常,至此生产者任务就全部编写完成。

 

 

 消费者

下面再来编写消费者任务,定义一个消费者任务类consumer,在类中定义一个data属性,它的作用是接收刚刚生产的数据,接着重载consumer构造方法,用于给data初始化使用while(true)无限消费数据,在循环体内定义一个同步锁为data的同步代码块,判断数据是否为空,数据不为空时说明数据已经生产了,但是还没消费。 

 

 

 


接下来就是消费数据,消费完数据以后,我们要重置数据,还要唤醒生产者线程,接着消费者线程等待,执行生产者任务和消费者任务

main

这里我们先将数据创建出来,然后分别创建一个生产者任务和一个消费者任务,将数据分别传递给生产者任务和消费者任务,下面分别创建一个生产者线程和一个消费者线程,将生产者任务传递生产者线程,将消费者任务传递给消费者线程,最后启动这两个线程。

 

 

 

 

从执行结果来看,生产者线程和消费者线程节奏非常顺畅,截取一部分结果来看,生产一个数据,消费一个数据,生产一个数据,消费一个数据,

 

 

 总结

最后总结一下本节的内容,本节演示了线程间通讯实例,生产者与消费者利用wait ,notify等待唤醒机制,让线程间友好协作完成任务,更高效的使用资源。 

posted @ 2022-05-03 19:46  小陈子博客  阅读(97)  评论(0)    收藏  举报