m个生产者和n个消费者和x个搬运者的java实现

生产者消费者问题(JAVA实现)
 版本一:
package cn.edu.nankai.producterandconsumer;

import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.swing.JOptionPane;

public class ConsumerAndProducer {
	
	private static int numberOfProducer;
	private static int numberOfConsumer;
	private static int eachWorksOfProducer;
	private static int eachWorksOfConsumer;
	private static int sizeOfBuffer = 2;
	private static Buffer buffer = new Buffer();
	
	public static void main(String[] args){
		numberOfProducer = Integer.parseInt(JOptionPane.showInputDialog("请输入你想要的生产者数量"));
		numberOfConsumer = Integer.parseInt(JOptionPane.showInputDialog("请输入你想要的消费者数量"));
		eachWorksOfProducer = Integer.parseInt(JOptionPane.showInputDialog("请输入你想要每个生产者生产的数量"));
		eachWorksOfConsumer = Integer.parseInt(JOptionPane.showInputDialog("请输入你想要每个消费者消费的数量"));
		sizeOfBuffer = Integer.parseInt(JOptionPane.showInputDialog("请输入缓冲区大小"));
		JOptionPane.showMessageDialog(null, "生产者数量是 " + numberOfProducer +"\n消费者数量是 " + numberOfConsumer+
				"\n每个生产者生产的数量是 " + eachWorksOfProducer + "\n每个消费者消费的数量是 " + eachWorksOfConsumer + 
				"\n缓冲区大小是 " + sizeOfBuffer);
		ExecutorService executor = Executors.newFixedThreadPool(numberOfConsumer + numberOfProducer);
		for(int i = 0;i < numberOfProducer;i++)
			executor.execute(new ProducerTask(i));
		for(int i = 0;i < numberOfConsumer;i++)
			executor.execute(new ConsumerTask(i));
		executor.shutdown();
		while(!executor.isTerminated());
		JOptionPane.showMessageDialog(null, "线程全部运行完毕\n");
	}
	
	private static class ProducerTask implements Runnable{
       
		int id;
		
		public ProducerTask(int id) {
			super();
			this.id = id;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
			int i = 1;
			try{
			for(int j = 0;j < eachWorksOfProducer;j++){
				System.out.println("Producer" + id + " writes " + i);
			    buffer.write(i++);
				Thread.sleep((int)(Math.random()*1000));
			}
			}catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private static class ConsumerTask implements Runnable{

		int id;
		
		public ConsumerTask(int id) {
			super();
			this.id = id;
		}

		@Override
		public void run() {
			// TODO Auto-generated method stub
				try {
					for(int i = 0;i < eachWorksOfConsumer;i++){
						System.out.println("Consumer" + id + " reads " + buffer.read());
					Thread.sleep((int)(Math.random()*2000));}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
}
版本二:
package cn.edu.nankai.pac;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Buffer {
	final String pro = "生产者";
	final String con = "消费者";
	private LinkedList queue = new LinkedList();
	private Lock lock = new ReentrantLock();
	private int indexOfBuffer = 0;
	private Condition notEmpty = lock.newCondition();
	private Condition notFull = lock.newCondition();
	private int size;
	private int id;
        
	Buffer(int id,int size){
		this.id = id;
		this.size = size;
	}
	
	public LinkedList getList(){
		return queue;
	}
	
	public void write(int value,int time,int pid,long tid){

		try {
			Thread.sleep(time = Information.randomTime(2,4));
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
		    Information.output("生产者 " + pid +"(线程号" + tid+ ")运行完毕");
		}
		Information.output("生产者 " + pid +"(线程号" + tid + ")生产用时" + time + "姓名:" + Information.NAME + " 学号:" + Information.ID);
		Information.output(pro + pid + "(线程号" + tid + ")试图进入缓冲区" + id);
		lock.lock();
		Information.output(pro + pid + "(线程号:" + tid + ")进入了第" + id + "个缓冲区,");
			try {
				while(queue.size() == size){
					Information.output("缓冲区" + id + "已满,"+ pro + pid + "(线程号:" + tid+ ")正在等待");
				    	notFull.await();
				}
				
				queue.offer(value);
				Information.which.offer(id);
				indexOfBuffer++;
				Information.output(pro + pid + "(线程号:" + tid + ")在第" + id +"个缓冲区生产了一个产品" + value + "缓冲区序号" + indexOfBuffer);
				notEmpty.signalAll();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				lock.unlock();
				Information.output(pro + pid + "(线程号:" + tid+ ")离开缓冲区" + id + "\n");
			}
	}
	
	@SuppressWarnings("finally")
	public int read(int time,int cid,long tid){
		int value = 0;
		
		Information.output(con + cid + "(线程号:" + tid + ")试图进入缓冲区" + id);
		lock.lock();
		Information.output(con + cid + "(线程号:" + tid + ")进入了第" + id + "个缓冲区");
			try {
				while(queue.size() == 0){
					Information.output("缓冲区" + id + "已空,"+ con + cid + "(线程号:" + tid+ ")正在等待");
				    notEmpty.await();
				}
				value = queue.remove();
				indexOfBuffer--;
				Information.output(con + cid + "(线程号:" + tid + ")再第" + id + "个缓冲区消费了一个产品" + value + "缓冲区序号:" + indexOfBuffer);
				notFull.signalAll();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				lock.unlock();
				Information.output(con + cid + "(线程号:" + tid + ")离开缓冲区" + id + "\n");
				try {
					Thread.sleep(time = Information.randomTime(2,4));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					//e.printStackTrace();
					Information.output("消费者 " + cid +"(线程号" + tid + ")运行完毕");
				}
				Information.output("从缓冲区" + id + " 的消费者 " + cid +"(线程号" + tid + ")消费用时" + time + "姓名:" + Information.NAME + " 学号:" + Information.ID);
				return value;
			}
	}
}
 package cn.edu.nankai.pac;

public class Consumer extends Thread{
	int cid;
	int i = 0;
	volatile static Integer count = 0;
	Consumer(int cid){
		this.cid = cid;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
			while(count <= 8){
				synchronized (count){
					if(count == 8){
						Information.output("消费者" + cid + "已停止运行");
						break;
					}
				int time = 0;
				if(Information.which.size() != 0){
					switch(Information.which.remove()){
					case 1:
						synchronized (count) {
							if(count < 8){
								count++;
							}else{
								break;
							}
						}
							Main.firstBuffer.read(time, cid,this.getId());
						break;
						
					case 2:
						synchronized (count) {
							if(count < 8){
								count++;
							}else{
								break;
							}
						}
							Main.secondBuffer.read(time, cid,this.getId());
						break;
					default:
						System.err.println("缓冲区选择错误");
						break;
					}
				}else{
					Information.output("所有缓冲区都是空的");
				}
				
				synchronized (count){
					if(count == 8){
						Information.output("消费者" + cid + "已停止运行");
						break;
					}
				}
			}
			}
	}
}
package cn.edu.nankai.pac;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;

public class Information {
	final static String NAME="王文涵";
	final static String ID="1212603";
	//static String s = "";
	public volatile static LinkedList which = new LinkedList();
	public static int whichBuffer(){
		return (int)(Math.random() * 100) % 2 == 0 ? 1 : 2;
	}
	
	public static int randomTime(int start,int end){
		return (int)(Math.random()*1000*(end - start)) + start*1000;
	}
	
	public static void output(String s){
		System.out.println(s);
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(new File("d:\\Result.txt"), true));
			writer.append(s + "\n\n\n");
			writer.flush();
			writer.close();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} // true代表追加
	}
}
package cn.edu.nankai.pac;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JOptionPane;

public class Main {

	public final static int numberOfProducer = 3;
	public final static int numberOfConsumer = 2;
	static Buffer firstBuffer = new Buffer(1,1);
    static Buffer secondBuffer = new Buffer(2,2);
    public volatile static Integer sum = 0;

    
	public static void main(String[] args){
	
	final ExecutorService executor = Executors.newFixedThreadPool(numberOfConsumer + numberOfProducer);
	for(int i = 0;i < numberOfProducer;i++)
		executor.execute(new Producter(i));
	for(int i = 0;i < numberOfConsumer;i++)
		executor.execute(new Consumer(i));
	executor.shutdown();
	while(!executor.isTerminated() && !(Consumer.count == 8 && Producter.count == 8)){
//		System.out.println("Consumer is " + Consumer.count + ",Producter is " + Producter.count);
//		try {
//			Thread.sleep(1000);
//		} catch (InterruptedException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
	executor.shutdownNow();
	JOptionPane.showMessageDialog(null, "线程全部运行完毕\n");
	System.out.println("all is over");
	}
}
package cn.edu.nankai.pac;

public class Producter extends Thread{
	
	int pid;
	int i = 0;
	volatile static Integer count = 0;
	Producter(int pid){
		this.pid = pid;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
			while(count <= 8){
				synchronized (count){
					if(count == 8){
						Information.output("消费者" + pid + "已停止运行");
						break;
					}
				int time = 0;
					switch(Information.whichBuffer()){
					case 1:
						synchronized (count) {
						if(count < 8){
					    count++;
						}else{
							break;
						}
						}
						Main.firstBuffer.write(i++, time, pid,this.getId());
						break;
					case 2:
						synchronized (count) {
						if(count < 8){
						count++;
						}else{
							break;
						}
						}
						Main.secondBuffer.write(i++, time, pid,this.getId());
						break;
					default:
						Information.output("缓冲区选择错误");
						break;
					}
				
				synchronized (count){
					if(count == 8){
						Information.output("生产者" + pid + "停止运行");
						break;
					}
				}
			}
		}
	}
}
版本三:(南开软件学院东哥操作系统典型题,无私分享给学妹们了)
package cn.edu.nankai.pac;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import static cn.edu.nankai.pac.Information.*;

public class Buffer {
   
	private LinkedList queue = new LinkedList();
	private Lock lock = new ReentrantLock();
	private Condition notEmpty = lock.newCondition();
	private Condition notFull = lock.newCondition();
	private int id;
	private int size;
	private int indexOfBuffer = 0;
        
	Buffer(int id,int size){
		this.id = id;
		this.size = size;
	}
	
	synchronized public int getListSize(){
		return queue.size();
	}
	
	public void write(int value,int pid,long tid,int type){
		String str = type == P ? pro : mov;
		output(str + pid + " 线程号:" + tid + "姓名:" + NAME + " 学号:" + ID);
		output(str + pid + " 线程号:" + tid + "试图进入缓冲区" + id);
		lock.lock();
		output(str + pid + " 线程号:" + tid + "进入了第" + id + "个缓冲区,");
			try {
				while(queue.size() == size){
					Information.output("缓冲区" + id + "已满,"+ str + pid + " 线程号:" + tid+ "正在等待");
				    	notFull.await();
				}
				
				queue.offer(value);
				which.offer(id);
				indexOfBuffer++;
				output(str + pid + " 线程号:" + tid + "在第" + id +"个缓冲区放入了一个产品" + value + "缓冲区序号" + indexOfBuffer);
				notEmpty.signalAll();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
				output(str + pid + "线程号:" + tid+ "离开了缓冲区" + id + "\n");
			}
	}
	
	public int read(int cid,long tid,int type){
		int value = 0;
		String str = type == C ? con : mov;
		output(str + cid + " 线程号:" + tid + "试图进入缓冲区" + id);
		lock.lock();
		output(str + cid + " 线程号:" + tid + "进入了第" + id + "个缓冲区");
			try {
				while(queue.size() == 0){
					output("缓冲区" + id + "已空,"+ str + cid + " 线程号:" + tid+ "正在等待");
				    notEmpty.await();
				}
				value = queue.remove();
				indexOfBuffer--;
				output(str + cid + " 线程号:" + tid + "在第" + id + "个缓冲区取出了一个产品" + value + "缓冲区序号:" + indexOfBuffer);
				notFull.signalAll();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
				output(str + cid + "(线程号:" + tid + ")离开缓冲区" + id + "\n");
			}
			return value;
	}
}
package cn.edu.nankai.pac;

import static cn.edu.nankai.pac.Information.*;

public class Consumer extends Thread{
	
	private int cid;
	private static Integer ccount = 0;
	
	public Consumer(int cid) {
		//super();
		this.cid = cid;
	}

	@Override
	public void run() {
		//super.run();
		while(true){
			System.out.println(con + ":" + ccount);
			synchronized (ccount) {
				if(ccount < totelProduct){
					ccount++;
					buffer[2].read(cid, this.getId(), C);
				}else{
					break;
				}
			}
			long time;
			try {
				Thread.sleep(time = Information.randomTime(2,4));
				output(con + cid + " 线程号:" + this.getId() + " 消费产品总共用时:" + ((double)time)/1000 + "秒");
			} catch (InterruptedException e) {
				e.printStackTrace();
				
			}
		}
		System.out.println(con + cid + " 线程号:" + this.getId() + "已经停止运行");
	}
	
	public void setCid(int cid) {
		this.cid = cid;
	}

	public int getCid() {
		return cid;
	}
	
}

 package cn.edu.nankai.pac;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;

import javax.swing.JOptionPane;

public class Information {
	
	//各种常量字符串和类型
	public final static String NAME="王文涵";
	public final static String ID="1212603";
	public final static String pro = "生产者";
	public final static String con = "消费者";
	public final static String mov = "移动者";
	public final static int P = 0;
	public final static int C = 1;
	public final static int M = 2; 
	
	//题目相关的变量
	public static int numberOfProducter = 3;
	public static int numberOfConsumer = 3;
	public static int numberOfMover = 2;
	public static int numberOfBuffer = 3;
	public static int totelProduct = 3;
	public static int []eachBufferSize = new int[numberOfBuffer];
	public volatile static LinkedList which = new LinkedList();
	public static Buffer [] buffer = new Buffer[numberOfBuffer];
	public static int ERR = 1000;
	
	private static void initBufferSize(){
		for(int i = 0;i < numberOfBuffer;i++)
			eachBufferSize[i] = 2;
	}
	
	public static void initBuffer(){
		initBufferSize();
		for(int i = 0;i < numberOfBuffer;i++)
			buffer[i] = new Buffer(i,eachBufferSize[i]);
	}
	
	public static void handleInput(){
		 numberOfProducter = Integer.parseInt(JOptionPane.showInputDialog("请输入第一个人的数量"));
		 numberOfConsumer = Integer.parseInt(JOptionPane.showInputDialog("请输入第二个人的数量"));
		 numberOfMover = Integer.parseInt(JOptionPane.showInputDialog("请输入第三个人的数量"));
		 numberOfBuffer = Integer.parseInt(JOptionPane.showInputDialog("请输入缓冲区的数量"));
		 totelProduct = Integer.parseInt(JOptionPane.showInputDialog("总共要生产的产品的数量"));
		 eachBufferSize = new int[numberOfBuffer];
		 for(int i = 0;i < numberOfBuffer;i++)
			 eachBufferSize[i] = Integer.parseInt(JOptionPane.showInputDialog("请输入第" + (i+1) + "个缓冲区的大小"));
	}
	
	public static int whichBuffer(){
		return (int)(Math.random() * 100) % 2 == 0 ? 1 : 2;
	}
	
	public static int randomTime(int start,int end){
		return (int)(Math.random()*1000*(end - start)) + start*1000;
	}
	
	public static void output(String s){
		System.out.println(s);
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(new File("d:\\Result.txt"), true));// true代表追加
			writer.append(s + "\n\n\n");
			writer.flush();
			writer.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		} 
	}
}
package cn.edu.nankai.pac;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JOptionPane;
import static cn.edu.nankai.pac.Information.*;

public class Main {
   
	public static void main(String[] args){
		initBuffer();
		final ExecutorService executor = Executors.newFixedThreadPool(numberOfConsumer + numberOfProducter + numberOfMover);
	    for(int i = 0;i < numberOfProducter;i++)
	    	executor.execute(new Producter(i));
	    for(int i = 0;i < numberOfMover;i++){
	    	Mover m = new Mover(i);
	    	m.setBuffer(buffer[i], buffer[i+1]);
	    	executor.execute(m);
	    }
	
	    for(int i = 0;i < numberOfConsumer;i++)
		    executor.execute(new Consumer(i));
	    executor.shutdown();
	    while(!executor.isTerminated()){
	    }
	    executor.shutdownNow();
	    JOptionPane.showMessageDialog(null, "线程全部运行完毕\n");
	    System.out.println("all is over");
	}
}
package cn.edu.nankai.pac;

import static cn.edu.nankai.pac.Information.output;
import static cn.edu.nankai.pac.Information.*;

public class Mover extends Thread{

	private int mid;
    private Integer mcount = 0; 
	private Buffer start = new Buffer(ERR, 0);
	private Buffer end = new Buffer(ERR,0);
	
	public Mover(int mid) {
		//super();
		this.mid = mid;
	}
	
	public void setBuffer(Buffer start,Buffer end){
		this.start = start;
		this.end = end;
	}
	
	@Override
	public void run() {
		//super.run();
		while(true){
			System.out.println(mov + mid +":" + mcount);
			//synchronized (mcount) {
				if(mcount < totelProduct){
					mcount++;
					int value = this.start.read(mid, this.getId(), M);
					long time;
					try {
						Thread.sleep(time = Information.randomTime(2,4));
						output(mov + mid + " 线程号:" + this.getId() + " 移动产品总共用时:" + ((double)time)/1000 + "秒");
					} catch (InterruptedException e) {
						e.printStackTrace();
					    output(mov + mid + " 线程号:" + this.getId() + "运行完毕");
					}
							this.end.write(value, mid, this.getId(), M);
				}else{
					break;
				}
			//}
		}
		System.out.println(mov + mid + " 线程号:" + this.getId() + "已停止运行");
	}
	
	public void setMid(int mid) {
		this.mid = mid;
	}

	public int getMid() {
		return mid;
	}
}
package cn.edu.nankai.pac;

import static cn.edu.nankai.pac.Information.*;

public class Producter extends Thread{
	
	private int pid;
	private  static Integer pcount = 0;
	
	public Producter(int pid) {
		//super();
		this.pid = pid;
	}

	@Override
	public void run() {
		//super.run();
			while(true){
				System.out.println(pro + ":" + pcount);
				long time;
					try {
						Thread.sleep(time = Information.randomTime(2,4));
						output(pro + pid + " 线程号:" + this.getId() + " 生产产品总共用时:" + ((double)time)/1000 + "秒");
					} catch (InterruptedException e) {
						e.printStackTrace();
					    output(pro + pid + " 线程号:" + this.getId() + "运行完毕");
					}
					//System.out.println("Reach there0");
					synchronized (pcount) {
						//System.out.println("Reach there1");
						if(pcount < totelProduct){
							pcount++;
							//System.out.println(pro + pid + " 线程号:" + this.getId() + "加一");
							buffer[0].write(0, pid, this.getId() , P);
						}else{
							System.out.println(pro + pid + " 线程号:" + this.getId() + "已经停止运行");
							break;
						}
				}
		}
	}
	
	public void setPid(int pid) {
		this.pid = pid;
	}

	public int getPid() {
		return pid;
	}
	
}

你可能感兴趣的:(操作系统,操作系统,生产者,消费者,多线程,java)