java语言基础(94)——线程间通信(等待唤醒机制)

生产者与消费者例子说明线程通信的等待唤醒机制

在多线程程序中,有时候,线程之间是有制约的,需要有一定的规则执行,典型的例子就是生产者与消费者之间的关系。此处我们以 老板  饭店  和顾客三者举例说明。

老板饭店顾客之间的关系:

老板与顾客之间共同的资源是饭店。

老板的工作是(生产者):

查看是否有多余的饭菜  

有  等会儿再做   

没有  做好饭菜  并通知顾客来吃饭

顾客的工作是(消费者):

看饭店是否有饭菜

有  消费  并通知老板做饭菜

没有  等会儿   

代码体现:

package ThreadDemo;
// 饭店
public class Restaurant {
  public String name;// 菜名
  public int price; // 价格
  public boolean flag=false;//用来表示有没有饭菜
}
package ThreadDemo;
// 卖家 对应于生产者
public class Seller implements Runnable {
  private int x;
  private Restaurant r;
  public Seller(Restaurant r){
	  this.r = r;
  }
  public void run(){
	while(true){
		  synchronized(r){
			  // 如果有饭菜就等会儿  
			  if(r.flag){
			    try {
					r.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			  }
			  if(x%2==0){
				  r.name = "水饺";
				  r.price = 10;
			  }else{
				  r.name = "包子";
				  r.price = 8;
			  }
			  // 饭菜做好后改变状态
			  r.flag = true;
			  x++;
			  // 并且通知顾客来吃饭  唤醒其它线程
			  r.notify();
		  }
	}
  }
}
package ThreadDemo;
// 买家 对应于消费者
public class Buyer implements Runnable{
	private Restaurant r;
  public Buyer(Restaurant r){
	  this.r=r;
  }
  public void run(){
	  while(true){
		  synchronized(r){
			  // 如果没有饭菜就等会儿
			  if(!r.flag){
				  try {
					r.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			  }
			  // 如果有就消费
			  System.out.println(r.name+":"+r.price);
			  // 标记为没有饭菜
			  r.flag = false;
			  // 并通知生产者继续生产 唤醒其它线程
			  r.notify();
		  }
	  }
  }
}
测试类

package ThreadDemo;

public class WaitNotifyDemo {
 
	public static void main(String[] args) {
		 Restaurant r = new Restaurant();
		 Seller s = new Seller(r);
		 Buyer b = new Buyer(r);
		 
		 Thread ts = new Thread(s);
		 Thread tb = new Thread(b);
		 
		 ts.start();
		 tb.start();

	}

}

我们会看到,生产一个,消费一个的效果。通过此例,我们可以清晰的了解线程的等待唤醒机制。

注意:此测试代码没有加停止条件,启动后将一直执行下去。不能直接用于实际开发。


你可能感兴趣的:(java)