版权声明:本博文仅供学习、参考、技术讨论,版权归笔者/译者所有。 https://blog.csdn.net/qq_38025219/article/details/84317828
前言:
线程开始运行,拥有自己的栈空间,但是如果每个运行中的线程,如果仅仅是孤立地运行,那么没有一点儿价值,或者是价值很小,如果多线程能够相互配合完成工作的话,这将带来巨大的价值,这也就是线程间的通信啦。在java中多线程间的通信使用的是等待/通知机制来实现的。
具体而言: 是指一个线程A1调用了对象B的wait()方法进入等待状态,而另一个线程A2调用了对象B的notify()或者notifyAll()方法,线程A1收到通知后从对象B的wait()方法返回,进而执行后续操作。上述的两个线程通过对象B来完成交互,而对象上的wait()和notify()/notifyAll()的关系就如同开关信号一样,用来完成等待方和通知方之间的交互工作。
代码设计:
本文以生产苹果和消费苹果为例子
AppleResource.java
package CP;
/**
*@author superxing
* @time 2018年11月21日
* @decrition 苹果资源
*/
public class AppleResource {
private String name;
private int count = 1;//苹果的初始数量
private boolean flag = false;//判断是否有需要线程等待的标志
/**
* 生产苹果
*/
public synchronized void product(String name){
while(flag){
//此时有苹果,等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name+count;//设置苹果的名称
count++;
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
flag=true;//有苹果后改变标志
notifyAll();//通知消费线程可以消费了
}
/**
* @author superxing
* @time 2018年11月21日
* 消费苹果
*/
public synchronized void consume(){
while(!flag){//如果没有苹果就等待
try{this.wait();}catch(InterruptedException e){}
}
System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费苹果1
flag = false;
notifyAll();//通知生产者生产苹果
}
}
MutilProducerConsumer.java
package CP;
/**
* @author superxing
* @time 2018年11月21日
* @decrition 多生产者多消费者模式
*/
public class MutilProducerConsumer {
public static void main(String[] args)
{
AppleResource r = new AppleResource();
Mutil_Producer pro = new Mutil_Producer(r);
Mutil_Consumer con = new Mutil_Consumer(r);
//生产者线程
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
//消费者线程
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
//启动线程
t0.start();
t1.start();
t2.start();
t3.start();
}
}
/**
* @author superxing
* @time 2018年11月21日
* @decrition 生产者线程
*/
class Mutil_Producer implements Runnable
{
private AppleResource r;
Mutil_Producer(AppleResource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.product("苹果");
}
}
}
/**
* @author superxing
* @time 2018年11月21日
* @decrition 消费者线程
*/
class Mutil_Consumer implements Runnable
{
private AppleResource r;
Mutil_Consumer(AppleResource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.consume();
}
}
}
代码思考:
通过网上寻找资料和思考,用两组条件对象(Condition也称为监视器)来实现等待/通知机制,也就是说通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。notifyAll()和signalAll()方法去唤醒池中的线程,然后让池中的线程又进入 竞争队列去抢占CPU资源,这样不仅唤醒了无关的线程而且又让全部线程进入了竞争队列中,而我们最后使用两种监听器分别监听生产者线程和消费者线程,这样的方式恰好解决前面两种方式的问题所在,我们每次唤醒都只是生产者线程或者是消费者线程而不会让两者同时唤醒,这样不就能更高效得去执行程序了吗?