生产者消费者问题

 

 

1. 使用栈来存放数据
    1.1 把栈改造为支持线程安全
    1.2 把栈的边界操作进行处理,当栈里的数据是0的时候,访问pull的线程就会等待。 当栈里的数据是10的时候,访问push的线程就会等待
2. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈
3. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台
4. 提供一个测试类,使两个生产者和三个消费者线程同时运行,结果类似如下 

生产者消费者问题_第1张图片

该程序主要有两部分代码:

(一)自定义的线程安全栈(如下所示)。

 用wait(), notify(), notifyAll实现

public class PCStack{
	public LinkedList stacks=new LinkedList<>();
	
	public synchronized void push(Character c) {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(stacks.size()>=10) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			};
		}else {
			stacks.addLast(c);
			this.notifyAll();
		}
		
	}
	
	public synchronized Character pull() {
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(stacks.size()<=0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}else {
			this.notifyAll();
			return stacks.removeLast();
		}
	}
	
	public synchronized Character peek() {
		return stacks.getLast();
	}
}

 使用Condition对象的:await, signal,signalAll 方法实现

public class PCStack{
	public LinkedList stacks=new LinkedList<>();
	public Lock lock=new ReentrantLock();
	public Condition condition=lock.newCondition();
	public void push(Character c) {
		lock.lock();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(stacks.size()>=10) {
			try {
				condition.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			};
		}else {
			stacks.addLast(c);
			condition.signalAll();
		}
		lock.unlock();
		
	}
	
	public Character pull() {
		lock.lock();
		try {
			Thread.sleep(100);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		if(stacks.size()<=0) {
			try {
				condition.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}else {
			condition.signalAll();
			Character ll=stacks.removeLast();
			lock.unlock();
			return ll;
		}
	}
	
	public synchronized Character peek() {
		return stacks.getLast();
	}
}

(二)测试类,其中有两个生产者和三个消费者(代码如下所示)。

public class P_C {
	public static void main(String[] args) {
		char[] products= {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
		final PCStack mystack=new PCStack();
		for(int i=0;i<3;i++) {
			int index=i+1;
			Thread producter=new Thread() {
				public void run() {
					while(true) {
						char c=products[(int)(Math.random()*26)];
						mystack.push(c);
						System.out.println("Producter"+index+" 压入:"+c);
					}
				}
			};
			producter.start();
		}
		
		for(int i=0;i<2;i++) {
			int index=i+1;
			Thread consumer=new Thread() {
				public void run() {
					while(true) {
						Character c=mystack.pull();
						if(c!=null) {
							System.out.println("Consumer"+index+" 弹出:"+c);
						}
					}
				}
			};
			consumer.start();
		}
	}
}

 

你可能感兴趣的:(学习心得)