多线程——生产者与消费者(多)问题解决

package 多线程;

public class PandC {

	public static void main(String[] args) {
//		Producer p= new Producer();
//		Consumer c = new Consumer();
//		new Thread(p,"生产者").start();
//		new Thread(p,"生产者").start();
//		new Thread(c,"消费者").start();
//		new Thread(c,"消费者").start();
		new Thread(new Producer(),"生产者").start();
		new Thread(new Consumer(),"消费者").start();
		new Thread(new Producer(),"生产者").start();
		new Thread(new Consumer(),"消费者").start();
	}
}
//通过单例模式 保证资源唯一
//class Resource{
//	private String name;
//	private int count;
//	private boolean flag=false;
//	static Resource r = new Resource();
//	private Resource() {
//	}
//	public static Resource getRes(){
//		return r;
//	}
//	public synchronized void produce(String name){
//		if(!flag)
//			try {
//				wait();//this.wait(); //this可省略
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		name = name+count++;
//		flag=false;
//		System.out.println(Thread.currentThread().getName()+" .........生产商品:"+count);
//		this.notify();//this可省略
//	}
//	public synchronized void consume(){
//		if(flag)
//			try {
//				wait();
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		flag=true;
//		System.out.println(Thread.currentThread().getName()+" ======消费商品:"+count);
//		notify();
//	}
//}
class Producer implements Runnable{
	Resource r = Resource.getRes();
	@Override
	public void run() {
		while(true)
			r.produce("商品:");
	}
}
class Consumer implements Runnable{
	Resource r = Resource.getRes();
	@Override
	public void run() {
		while(true)
			r.consume();
	}
}

/*
 输出:     				生产一个   被消费两次
 生产者 .........生产商品:44500
消费者 ======消费商品:44500
消费者 ======消费商品:44500
生产者 .........生产商品:44501
消费者 ======消费商品:44501
消费者 ======消费商品:44501
					生产两个  却只被消费一个
生产者 .........生产商品:45841
生产者 .........生产商品:45842
消费者 ======消费商品:45842
生产者 .........生产商品:45843
消费者 ======消费商品:45843
 * 
 解决办法   每次线程被唤醒 都去判断一次flag  并 需要唤醒所有线程 否则会出现所有线程全部等待
 代码:*/
 class Resource{
	private String name;
	private int count;
	private boolean flag=false;
	static Resource r = new Resource();
	private Resource() {
	}
	public static Resource getRes(){
		return r;
	}
	public synchronized void produce(String name){
		while(!flag)
			try {
				wait();//this.wait(); //this可省略
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		name = name+count++;
		flag=false;
		System.out.println(Thread.currentThread().getName()+" .........生产商品:"+count);
		this.notifyAll();//this可省略
	}
	public synchronized void consume(){
		while(flag)
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		flag=true;
		System.out.println(Thread.currentThread().getName()+" ======消费商品:"+count);
		notifyAll();
	}
}

对于多个生产者和消费者

为什么要定义while判断标记??

原因:让被唤醒的线程,再一次判断标记

为什么定义notifyAll

原因:要唤醒对方线程,要唤醒对方线程只能通过唤醒同一锁上的所有线程

如果值用notify的话,容易出现唤醒本方线程的情况,导致两方线程都处于等待中

本文出自 “要么拼命,要么滚回去!” 博客,请务必保留此出处http://jiangzuun2014.blog.51cto.com/8732469/1441234

多线程——生产者与消费者(多)问题解决

上一篇:BufferingForwardingAppender in log4net


下一篇:spring mvc3.2.4生成的json配置