多线程Producer-Consumer的多种实现
更多类型Product-Consumer的实现:https://github.com/Al-assad/Produer-Consumer
1、使用老式synchronized互斥锁实现:
/**
* @see
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:15:49
* @version V1.0
* Description: Product-Consumer模型使用的Product类
*/
public class Product {
private int typeId; //产品种类编号
public Product(int typeId){
this.typeId = typeId;
}
public int getType(){
return this.typeId;
}
public String toString(){
return "Product"+this.typeId;
}
}
/**
* @see Product
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 下午4:57:04
* @version V1.0
* Description: product仓库类,负责维护products列表的同步更新;
*/
import java.util.*;
public class ProductRepository {
private Queue<Product> products = new LinkedList<Product>(); //产品列表
private final int limit; //仓库中的产品最大存放量
public ProductRepository(int limit){
this.limit = limit;
}
//任务线程发送product对象到本products
public synchronized void send(Product product) throws InterruptedException{
while(products.size() >= limit)
wait();
products.offer(product);
// System.out.println(products.size()); //打印仓库product数量
notifyAll();
}
//任务线程从本products获取一个product对象
public synchronized Product get() throws InterruptedException{
while(products.size() == 0)
wait();
Product product = null;
product = products.poll();
// System.out.println(products.size()); //打印仓库product数量
notifyAll();
return product;
}
public synchronized Queue<Product> getProducts(){
return products;
}
public int getLimit(){
return limit;
}
}
@see Product.java ProductRepository.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:19:31
* @version V1.0
* Description: Product-Consumer模型使用的Consumer类;
*
*/
import java.util.concurrent.*;
import java.util.*;
public class Consumer implements Runnable{
private ProductRepository repository;
private static volatile int count = 0; //记录累计Consumer的创建数量
private int id = 0; //记录Consumer的id
public Consumer(ProductRepository repository){
this.repository = repository;
id = count;
count++;
}
public String toString(){
return "Producer"+id;
}
public void run(){
try{
while(!Thread.interrupted()){
Product product = repository.get(); //在这里可以通过product.getType()获取product种类,采取不同的处理操作
System.out.println(this+" got "+product);
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(500)); //模拟消费时间
}
}catch(InterruptedException ex){
System.out.println(this+" intrrupted!");
}
}
}
/**
* @see Product.java ProductRepository.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:19:05
* @version V1.0
* Description: Product-Consumer模型使用的Producer类
*/
import java.util.concurrent.*;
import java.util.*;
public class Producer implements Runnable{
private ProductRepository repository;
private int typeId; //记录生产product的种类id
private static volatile int count = 0; //记录累计Producer的创建数量
private int id = 0; //记录Producer的id
public Producer(ProductRepository repository,int typeId){
this.typeId = typeId;
this.repository = repository;
id = count;
count++;
}
public String toString(){
return "Producer"+id;
}
public void run(){
try{
while(!Thread.interrupted()){
Product product = new Product(typeId); //生产工作分配到各线程,减少高创建成本对象的创建时间;
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(500)); //模拟生产时间
System.out.println(this+" sent "+product);
repository.send(product);
}
}catch(InterruptedException ex){
System.out.println(this+" intrrupted!");
}
}
}
/**
* @see Product.java ProductRepository.java Consumer.java Producer.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:25:00
* @version V1.0
* Description: 单一种类product测试类;
* 每一个Driver实例只能实现一种类型的Product的交易;
*/
import java.util.concurrent.*;
public class Driver {
private ProductRepository repository;
private int typeId; //指定该driver交易使用的product种类;
public Driver(int typeId,int limit,int producerSize,int consumerSize,int runSec) throws InterruptedException{
this.typeId = typeId;
repository = new ProductRepository(limit);
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<producerSize;i++)
exec.execute(new Producer(repository,typeId));
for(int i=0;i<consumerSize;i++)
exec.execute(new Consumer(repository));
TimeUnit.SECONDS.sleep(runSec);
exec.shutdownNow();
}
public int getTypeId(){
return this.typeId;
}
/* //Test
public static void main(String[] args) throws InterruptedException{
new Driver(0,10,20,25,10);
// new Driver(1,8,10,10,10);
// new Driver(2,15,12,5,10);
}*/
}
2、使用BlockingQueue实现;
/**
* @see Product.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:19:05
* @version V1.0
* Description: Product-Consumer模型使用的Producer类
*/
import java.util.concurrent.*;
import java.util.*;
public class Producer implements Runnable{
private BlockingQueue<Product> products;
private int typeId; //记录生产product的种类id
private static volatile int count = 0; //记录累计Producer的创建数量
private int id = 0; //记录Producer的id
public Producer(BlockingQueue<Product> products,int typeId){
this.typeId = typeId;
this.products = products;
id = count;
count++;
}
public String toString(){
return "Producer"+id;
}
public void run(){
try{
while(!Thread.interrupted()){
Product product = new Product(typeId); //生产工作分配到各线程,减少高创建成本对象的创建时间;
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(500)); //模拟生产时间
products.put(product);
System.out.println(this+" sent "+product);
}
}catch(InterruptedException ex){
System.out.println(this+" intrrupted!");
}
}
}
/**
* @see Product.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:19:31
* @version V1.0
* Description: Product-Consumer模型使用的Consumer类;
*
*/
import java.util.concurrent.*;
import java.util.*;
public class Consumer implements Runnable{
private BlockingQueue<Product> products;
private static volatile int count = 0; //记录累计Consumer的创建数量
private int id = 0; //记录Consumer的id
public Consumer(BlockingQueue<Product> products){
this.products = products;
id = count;
count++;
}
public String toString(){
return "Producer"+id;
}
public void run(){
try{
while(!Thread.interrupted()){
Product product = products.take(); //在这里可以通过product.getType()获取product种类,采取不同的处理操作
System.out.println(this+" got "+product);
TimeUnit.MILLISECONDS.sleep(new Random().nextInt(500)); //模拟消费时间
}
}catch(InterruptedException ex){
System.out.println(this+" intrrupted!");
}
}
}
/**
* @see
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:15:49
* @version V1.0
* Description: Product-Consumer模型使用的Product类
*/
public class Product {
private int typeId; //产品种类编号
public Product(int typeId){
this.typeId = typeId;
}
public int getType(){
return this.typeId;
}
public String toString(){
return "Product"+this.typeId;
}
}
/**
* @see Product.java Consumer.java Producer.java
* @author Al_assad yulinying_1994@outlook.com
* @date 2016年10月28日 上午1:25:00
* @version V1.0
* Description: 单一种类product测试类;
* 每一个Driver实例只能实现一种类型的Product的交易;
*/
import java.util.concurrent.*;
public class Driver {
private BlockingQueue<Product> products;
private int typeId; //指定该driver交易使用的product种类;
public Driver(int typeId,int limit,int producerSize,int consumerSize,int runSec) throws InterruptedException{
this.typeId = typeId;
products = new ArrayBlockingQueue<Product>(limit);
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<producerSize;i++)
exec.execute(new Producer(products,typeId));
for(int i=0;i<consumerSize;i++)
exec.execute(new Consumer(products));
TimeUnit.SECONDS.sleep(runSec);
exec.shutdownNow();
}
public int getTypeId(){
return this.typeId;
}
//Test
public static void main(String[] args) throws InterruptedException{
new Driver(0,10,20,25,10);
// new Driver(1,8,10,10,10);
// new Driver(2,15,12,5,10);
}
}