java线程的同步中notify和wait方法之生产消费实例讲解

aa.wait()

将执行aa.wait()的当前线程转入阻塞状态,让出CPU的控制权,释放对aa的锁定

this.notify():

功能:

不是叫醒正在执行this.notify()的当前线程
而是叫醒一个现在正在wait this对象的其他线程,如果有多个线程正在wait this对象,通常是叫醒最先wait this对象的线程,但具体是叫醒哪一个,这是由系统调度器 控制,程序员无法控制。

假设执行aa.notify()的当前线程为T1,如果当前时刻有其他线程因为执行了aa.wait()而陷入阻塞状态,则叫醒其中的一个,所谓叫醒某个线程就是另该线程从因为wait而陷入阻塞的状态转入就绪状态

aa.notifyAll()叫醒其他所有的因为执行了aa.wait()而陷入阻塞状态的线程

假设现在有T1、T2、T3、T4四个线程,在T1线程中执行了aa.notify()语句,则即便此时T1、T2、T3没有一个线程因为wait aa对象而陷入阻塞状态,T4线程中执行aa.notify方法时也不会有任何错误。

生产消费问题【经典问题】

一个仓库最多容纳6个产品,制造商现在要制造20件产品存入仓库,消费者要从仓库取出这20件产品来消费
制造商制造产品和消费者取出产品的速度很可能是不一样的,编程实现两者的同步

class SynStack 
{
	private char[] data = new char[6];
	private int cnt = 0; //表示数组有效元素的个数
	
	public synchronized void push(char ch)
	{
		while (cnt == data.length)
		{
			try
			{
				this.wait();	//使生产线程进入阻塞状态,消费线程开始执行
			}
			catch (Exception e)
			{
			}
		}
		this.notify(); 
		
		data[cnt] = ch;
		++cnt;
		System.out.printf("生产线程正在生产第%d个产品,该产品是: %c\n", cnt, ch);
	}
	
	public synchronized char pop()
	{
		char ch;
		
		while (cnt == 0)
		{
			try
			{
				this.wait();
			}
			catch (Exception e)
			{
			}
		}
		this.notify();		//因为生产线程进入阻塞,执行此语句后,消费线程会进入就绪状态,但是此时消费者有商品可以消费且是synchronized,所以先执行消费过程
		ch = data[cnt-1];
		
		System.out.printf("消费线程正在消费第%d个产品,该产品是: %c\n", cnt, ch);
		
		--cnt;
		return ch;		
	}	
}

class Producer implements Runnable
{
	private SynStack ss = null;
	
	public Producer(SynStack ss)
	{
		this.ss = ss;
	}
	
	public void run() // throws Exception
	{
		char ch;
		
		for (int i=0; i<20; ++i)
		{
				
			ch = (char)('a'+i);
			ss.push(ch);
		}
	}
}

class Consumer implements Runnable
{
	private SynStack ss = null;
	
	public Consumer(SynStack ss)
	{
		this.ss = ss;
	}
	
	public void run()
	{
		for (int i=0; i<20; ++i)
		{
			try{
			Thread.sleep(100);	//使消费比生产稍慢些
			}
			catch (Exception e){			
			}
			ss.pop();
		}
	}
}


public class Rain
{
	public static void main(String[] args)
	{
		SynStack ss = new SynStack();
		Producer p = new Producer(ss);
		Consumer c = new Consumer(ss);
		Thread t1 = new Thread(p);
		t1.start();
				
		Thread t2 = new Thread(c);
		t2.start();
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值