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操做的好處在哪裏?在實現代碼的過程當中說一個細節問題當顧客吃了一個饅頭以後就會通知廚師這個線程來生產饅頭,廚師生產一個饅頭也會去通知顧客來吃饅頭。這樣的思路就和觀察者思路差很少能解決生產者與消費者的耦合。說高大上點就是生產者幹本身的事情,消費者幹本身的事情,經過碗中消息來通知生產者該幹嗎,消費者該幹嗎。這樣的話就把生產者和消費者的關係解耦了。

相關文章
相關標籤/搜索