146_多线程(线程间通信-生产者消费者)

一个生产者一个消费者
class ProducerConsumer{
	public static void main(String[] args){
		Resource r = new Resource();
		Producer pro = new Producer(r);
		Consumer con = new Consumer(r);
		
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(con);
		
		t1.start();
		t2.start();
	}
}

class Resource{
	private String name;
	private int count = 1;
	private boolean flag = false;
	
	public synchronized void set(String name){
		if(flag)
			try{wait();}catch(Exception e){}
		this.name = name +"--"+count++;
		System.out.println(Thread.currentThread().getName()+
		"-生产者-"+this.name);
		flag = true;
		this.notify();
	}
	
	public synchronized void out(){
		if(!flag)
			try{wait();}catch(Exception e){}
		System.out.println(Thread.currentThread().getName()+
		"-消费者-"+this.name);
		flag = false;
		this.notify();
	}
}

class Producer implements Runnable{
	private Resource res;
	
	Producer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.set("+商品+");
		}
	}
}

class Consumer implements Runnable{
	private Resource res;
	
	Consumer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.out();
		}
	}
}

两个生产者两个消费者。改动如下。
class ProducerConsumer{
	public static void main(String[] args){
		Resource r = new Resource();
		Producer pro = new Producer(r);
		Consumer con = new Consumer(r);
		
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(pro);
		Thread t3 = new Thread(con);
		Thread t4 = new Thread(con);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

运行结果会出现另外两种情况:
1.生产者生成了两次,消费者只取一次
2.生产者生成一次,消费者取两次
发生这两种情况是因为没有判断标记flag。需要将if(flag)改为while(flag)。
但只修改这点,会导致所有进程都处于全部等待状态。所以要把notify()改为notifyAll();
但是改为notifyAll()唤醒的是所有线程,即同时包括生产者和消费者。改进方法见下一篇笔记。
/*
对于多个生产者和消费者
为什么要定义while判断标记?
原因:让被唤醒的线程再进行一次标记判断

为什么定义notifyAll()?
因为需要唤醒对方线程。用notify()容易出现唤醒
本方线程的情况,导致程序中的所有线程都等待。
*/class ProducerConsumer{
	public static void main(String[] args){
		Resource r = new Resource();
		Producer pro = new Producer(r);
		Consumer con = new Consumer(r);
		
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(pro);
		Thread t3 = new Thread(con);
		Thread t4 = new Thread(con);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

class Resource{
	private String name;
	private int count = 1;
	private boolean flag = false;
	
	public synchronized void set(String name){
		while(flag)
			try{wait();}catch(Exception e){}
		this.name = name +"--"+count++;
		System.out.println(Thread.currentThread().getName()+
		"-生产者-"+this.name);
		flag = true;
		this.notifyAll();
	}
	
	public synchronized void out(){
		while(!flag)
			try{wait();}catch(Exception e){}
		System.out.println(Thread.currentThread().getName()+
		"-消费者-"+this.name);
		flag = false;
		this.notifyAll();
	}
}

class Producer implements Runnable{
	private Resource res;
	
	Producer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.set("+商品+");
		}
	}
}

class Consumer implements Runnable{
	private Resource res;
	
	Consumer(Resource res){
		this.res = res;
	}
	public void run(){
		while(true){
			res.out();
		}
	}
}

猜你喜欢

转载自317324406.iteye.com/blog/2250424