线程间通讯(wait、notify应用)
引言
线程间如何通讯?通讯的方式其实有好几种,其中有一种就是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等待唤醒机制,让线程间友好协作完成任务,更高效的使用资源。
附录:
笔记完整文本:
线程间如何通讯?通讯的方式其实有好几种,其中有一种就是wait裸体反方式,与此相关的,还有一个比较经典的例子,那就是生产者与消费者,生产者指的是生产者线程,消费者指的是消费者形成,生产者县城负责生产数据,消费者县城负责消费数据,数据还没生产的时候,消费者现成先等待,与此同时生产者线程开始生产数据,数据生产以后叫醒等待中的消费者现成起来消费数据,随后生产者线程等待消费者现场开始消费数据,消费完数据以后,交行等待中的生产者线程,其他生产数据如此繁复,下面来编写一个生产者与消费者的例子。 一共有三个步骤,第一步编写一个数据类,第二步编写一个伸展者任务,第三步编写一个消费者任务。首先来编写一个数据类,定义一个描述数据的类data,在类中定义一个存放数据的属性message,随后定义一个获取数据的方法,get message再定义一个设置数据的方法。Set message。这是数据类编写完成再来编写生产者任务,定义一个生产者任务类,producer在另里面定一个data类型的属性,它主要是用于传递数据,然后重载producer构造方法,用于初始化data,接着编写任务部分,定义一个计数器用于给数据编号,方便后面观察使用VR处无限生产数据,定义一个同步所为德操的同步代码块,在同步代码块中先判断数据是否为空,当数据为空时开始生产数据,数据生产完以后打印出来,目的是为了和消费数据进行对比,生产一个消费一个接着调用notify方法唤醒在手上等待的单个线条。 这里唤醒的是消费者现成,再接着使当前现场等待,也就是使生产者线程等待等消费者现成消费数据,他消费完数据以后会唤醒生长者线程,最后使用穿上去捕获胃头方法抛出的异常,至此生产者任务就全部编写完成。下面再来编写消费者任务,定义一个消费者任务类,consumer在类中定义一个贝塔属性,它的作用是接收刚刚生产的数据,接着重载consumer构造方法,用于给德塔初始化使用VR处无限消费数据,在循环体内定义一个同步所谓德塔的同步大板块,判断数据是否为空,数据不为空时说明数据已经生产了,但是还没消费。 接下来就是消费数据,消费完数据以后,我们要重置数据,还要唤醒生产者线程,接着消费者现成的贷执行生产者任务和消费者任务,这里我们先将数据创建出来,然后分别创建一个深战者任务和一个消费者任务,将数据分别传递给圣战者任务和消费者任务,下面分别创建一个圣战的线程和一个消费者现场,将伸展者任务传递给伸展者县城,将消费者任务传递给消费者县城,最后启动这两个线程。从执行结果来看,生产者线程和消费者线程节奏非常顺畅,截取一部分结果来看,生产一个数据,消费一个数据,生产一个数据,消费一个数据,最后总结一下本节的内容,本节演示了县城间通讯实例,生产者与消费者利用wait notify等待唤醒机制,让县城间友好协作完成任务,更高效的使用资源。