Java入门到精通——基础篇之多线程实现简单的PV操做的进程同步

1、概述
    PV操做是对信号量进行的操做。

    进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另外一个进程的消息,当一个进程没有获得另外一个进程的消息时应等待,直到消息到达才被唤醒。举例:就像消费者与生产者的关系,说吃馒头把有一个碗能盛下6个馒头,厨师不停的生产馒头,顾客不停的吃馒头,此时厨师与顾客的关系就是同步。(以下图)java

    

    下面我就为你们利用java多线程的代码实现这个操做的过程。多线程

2、代码展现。并发

一、ManTou.javaide

package com.gaowei.PV;
	
	public class ManTou {
	
		int id; 
		ManTou(int id) {
			this.id = id;
		}
		public String toString() {
			return "ManTou : " + id;
		}
	}


二、厨师类Pclient.javathis

package com.gaowei.PV;
	
	public class PClient implements Runnable {
	
		private SyncStack ss=null;
		public PClient(SyncStack ss){
			this.ss=ss;
		}
		@Override
		public void run() {
			for (int i = 0; i < 20; i++) {
				ManTou mt=new ManTou(i);
				ss.push(mt);
				System.out.println("生产了:"+mt);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
	
		}
	
	}


三、顾客类Vclient.javaspa

package com.gaowei.PV;
	
	public class VClient implements Runnable {
		private SyncStack ss=null;
		public VClient(SyncStack ss){
			this.ss=ss;
		}
		@Override
		public void run() {
			for(int i=0; i<20; i++) {
				ManTou mt = ss.pop();
				System.out.println("消费了: " + mt);
				try {
					Thread.sleep(6000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}		
			}
		}
	
	}


四、碗类SyncStack.java线程

package com.gaowei.PV;
	
	public class SyncStack {
			private int index=0;
			ManTou[] arrMT=new ManTou[6];
			
			//添加馒头
			public synchronized void push(ManTou mt){
				while (index==arrMT.length) {
				try {
					this.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
					
				}
				this.notifyAll();
				arrMT[index]=mt;
				index++;
			}
			
			
			//吃馒头
			public synchronized  ManTou pop(){
				while(index==0){
					try {
						this.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				this.notifyAll();
				index--;
				return arrMT[index];
			}
	}


五、客户端显示效果代码PVClient.javacode

package com.gaowei.PV;
	
	public class PVClient {
	
		public static void main(String[] args) {
			
			SyncStack ss = new SyncStack();
			PClient p = new PClient(ss);
			VClient v= new VClient(ss);
		
			new Thread(p).start();
			new Thread(v).start();
		}
	
	}


六、效果图进程


    因为顾客吃馒头慢要6s吃个馒头,而厨师作馒头快1s就能作一个馒头因此从图中的分布你们就能够发现厨师作到了第6个馒头了消费者才吃了1个馒头接下来因为碗中只能盛下6个馒头因此厨师只有等着顾客吃一个而后在放一个馒头到碗里,一直到最后厨师20个馒头作完了顾客还得继续把剩下的6个馒头吃完才能结束。同步

3、总结。

    利用多线程实现了PV操做了接下了就要思考一下PV操做的好处在哪里?在实现代码的过程当中说一个细节问题当顾客吃了一个馒头以后就会通知厨师这个线程来生产馒头,厨师生产一个馒头也会去通知顾客来吃馒头。这样的思路就和观察者思路差很少能解决生产者与消费者的耦合。说高大上点就是生产者干本身的事情,消费者干本身的事情,经过碗中消息来通知生产者该干吗,消费者该干吗。这样的话就把生产者和消费者的关系解耦了。

相关文章
相关标签/搜索