流世幻羽

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一般的的等待和唤醒机制

/*
 生产者,消费者。


代码完成,加入同步和等待唤醒机制后,可以实现,生产一个,就消费一个。

可是在实际开发中,生产者和消费者,不是一个。有可能是多个
也就是有多个生产者生产,有多个消费者消费。


造成数据错误的原因:当生产者消费者多个时,
本方的线程有可能唤醒本方的线程,而且,本方被唤醒后,没有判断标记,就进行了执行,
会到导致原来本方的操作还没有被对方所操作就已经被覆盖了。

生产者1,进行了生产后,将本方生产者2唤醒,生产者2没有判断标记直接继续生产,
导致生产者1的产品还没有被消费就覆盖了。

解决方式:因为有本方唤醒本方的情况,所以必须每次的醒来都要判断一次标记。

判断标记的动作要执行多次。所以不使用if,而是使用while.


当进行while标记判断后,本方唤醒本方的动作还会发生,但是本方被唤醒后,继续判断标记,
虽然没有将前一次操作覆盖,但是导致了程序中的线程都处于了等待状态。
导致程序处于死锁状态。



到这里,发现,原因,有两个:
1,是判断标记。通过循环判断比较搞定。
2,一定要唤醒对方。notify是唤醒一个,这个线程有可能是本方,也有可能是对方。
	干脆,无论是本方还是对方,全唤醒。通过notifyAll搞定。


*/
class Res
{
	private String name;
	private int count  = 0;
	private boolean b = false;
	public synchronized void set(String name)
	{
		while(b)
			try{this.wait();}catch(Exception e){}
												
		this.name = name+"----"+count;

		count++;

		System.out.println(Thread.currentThread().getName()+".....生产者...."+this.name);

		b = true;
		this.notifyAll(); 
	}

	public synchronized void out()
	{
		while(!b)
			try{this.wait();}catch(Exception e){}
		System.out.println(Thread.currentThread().getName()+"----消费者---"+this.name);
		b = false;
		this.notifyAll();
	}
}


class Pro implements Runnable
{
	private Res r;
	Pro(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			r.set("产品");
		}
	}
}
class Cus implements Runnable
{
	private Res r;
	Cus(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			r.out();
		}
	}
}



class ProCusDemo 
{
	public static void main(String[] args) 
	{
		Res r = new Res();
		Pro p = new Pro(r);
		Cus c = new Cus(r);

		Thread t1 = new Thread(p);
		Thread t2 = new Thread(p);
		Thread t3 = new Thread(c);
		Thread t4 = new Thread(c);
		//t1,t2都是生产者。
		//t3,t3都是消费者。
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

  

posted on 2018-03-18 23:42  流世幻羽  阅读(241)  评论(0编辑  收藏  举报