使用synchronized实现生产者消费者

生产者消费者程序可使用多种方法实现,有使用synchronized关键字,Lock对象,semaphore同步工具。今天用synchronized实现时碰到两个问题,一个是报 IllegalMonitorStateException ,另一个是碰到死锁。死锁暂时解决不了。

生产者消费者有一个生产者一个消费者及多个生产者多个消费者。

一个生产者一个消费者

package cn.bj.demo.spring.javaevent.pc.sync;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 生产者消费者,假设有个传送带,生产者往传送带上放产品,消费者从传送带上取产品
 * 
 * */
public class ProducerAndConsumer {
	private static int MAX_SIZE = 2;  //传送带上最多能放产品数
	private List<Product> products = null; //传送带
	private ProducerTask pTask; //生产者任务
	private ConsumerTask cTask; //消费者任务
	private Producer p; //生产者
	
	public ProducerAndConsumer() {
		p = new Producer();
		products = new ArrayList<Product>();
		pTask = new ProducerTask(p, products);
		cTask = new ConsumerTask(products);
		
		Thread pThread = new Thread(pTask);
		pThread.setName("producer thread");
		pThread.start();
		
		Thread cThread = new Thread(cTask);
		cThread.setName("consumer thread");
		cThread.start();
		
		try {
			Thread.currentThread().join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("construct is over");
		
	}
	
	public static void main(String[] args) {
		
		ProducerAndConsumer pac = new ProducerAndConsumer();
	}
	
	
	class ProducerTask implements Runnable {
		
		private Producer producer;
		private List<Product> products;
		
		public ProducerTask() {
			// TODO Auto-generated constructor stub
		}
		
		public ProducerTask(Producer producer, List<Product> products) {
			this.producer = producer;
			this.products = products;
		}

		@Override
		public void run() {
			synchronized(products) {
				while (true) {
					try {
						while (products.size() >= MAX_SIZE) {
							products.wait();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					while (products.size() < MAX_SIZE) {
						Product p = producer.produce();
						products.add(p);
						try {
							TimeUnit.SECONDS.sleep(1);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						products.notify();
					}
				}
			}
			
		}
		
	}
	
	class ConsumerTask implements Runnable {
		private List<Product> products;
		
		public ConsumerTask(List<Product> products) {
			this.products = products;
		}
		
		@Override
		public void run() {
			synchronized(products) {
				while (true) {
					try {
						while (products.size() < MAX_SIZE) {
							products.wait();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					while (products.size() > 0) {
						Product p = products.remove(0);
						System.out.println(Thread.currentThread().getName() + " consummed a product, id = " + p.getId());
						try {
							TimeUnit.SECONDS.sleep(1);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						products.notify();
					}
				}
			}
			
		}
		
	}
	
	class Producer {
		public Product produce() {
			Product p = new Product();
			System.out.println("produced product, id = " + p.getId());
			return p;
		}
	}
	
}

多生产者多消费者

package cn.bj.demo.spring.javaevent.pc.sync;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 多个生产者,多个消费者
 * 
 * */
public class MultiProducerAndMultiConsumer {
	private static int MAX_SIZE = 10;
	private List<Product> products = null; //产品容器
	private List<ProducerTask> pTasks; //生产者任务组
	private List<ConsumerTask> cTasks; //消费者任务组
	private Object pLock; //生产者锁
	private Object cLock; //消费者锁
	private Producer p; //生产者
	
	public MultiProducerAndMultiConsumer() {
		p = new Producer();
		pLock = new Object();
		cLock = new Object();
		pTasks = new ArrayList<ProducerTask>();
		cTasks = new ArrayList<ConsumerTask>();
		String pName = "product thread, number";
		String cName = "consumer thread, number";
		products = new ArrayList<Product>(10);
		
		for (int i = 0; i < 10; i ++) {
			ProducerTask pTask = new ProducerTask(p, products);
			pTasks.add(pTask);
			Thread pThread = new Thread(pTask);
			pThread.setName(pName + i);
			pThread.start();
		}
		
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		for (int i = 0; i < 10; i++) {
			ConsumerTask cTask = new ConsumerTask(products);
			cTasks.add(cTask);
			Thread cThread = new Thread(cTask);
			cThread.setName(cName + i);
			cThread.start();
		}
		
		try {
			Thread.currentThread().join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("construct is over");
		
	}
	
	public static void main(String[] args) {
		
		MultiProducerAndMultiConsumer pac = new MultiProducerAndMultiConsumer();
	}
	
	
	class ProducerTask implements Runnable {
		
		private Producer producer;
		private List<Product> products;
		
		public ProducerTask() {
			// TODO Auto-generated constructor stub
		}
		
		public ProducerTask(Producer producer, List<Product> products) {
			this.producer = producer;
			this.products = products;
		}

		@Override
		public void run() {
			while (true) {
				synchronized(pLock) {
					try {
						while (products.size() == MAX_SIZE) {
							pLock.wait();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					Product p = producer.produce();
					products.add(p);
					try {
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (products.size() == 3) {
						synchronized(cLock) {
							System.out.println("notify all consumer");
							cLock.notifyAll();
						}
					}
				}
			}
			
		}
		
	}
	
	class ConsumerTask implements Runnable {
		private List<Product> products;
		
		public ConsumerTask(List<Product> products) {
			this.products = products;
		}
		
		@Override
		public void run() {
			while (true) {
				synchronized(cLock) {
					try {
						while (products.size() == 0) {
							cLock.wait();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					Product p = products.remove(0);
					System.out.println("--------" + Thread.currentThread().getName() + " consummed a product, id = " + p.getId());
					try {
						TimeUnit.SECONDS.sleep(2);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized(pLock) {
						if (products.size() == 3) {
							System.out.println("notify all producer");
							pLock.notifyAll();
						}
					}
				}
			}
			
		}
		
	}
	
	class Producer {
		public Product produce() {
			Product p = new Product();
			System.out.println(Thread.currentThread().getName() + " produced product, id = " + p.getId());
			return p;
		}
	}
	
}
package cn.bj.demo.spring.javaevent.pc.sync;

public class Product {
	public static int serialNo = 0;
	
	private Integer id;
	
	protected Product(Integer id) {
		setId(id);
	}
	
	public Product() {
		this.id = serialNo ++;
	}
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		if (id.intValue() < 0) {
			throw new RuntimeException(id + "can not be negative");
		}
		this.id = id;
	}

	
}

上边多生产者多消费者代码里因ProducerTask和ConsumerTask中获取锁的顺序不同,会导致死锁。暂时不处理。。。

发布了35 篇原创文章 · 获赞 14 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/U___U/article/details/103034478