完全理解Java中生產者和消費者模型.docx_第1頁
完全理解Java中生產者和消費者模型.docx_第2頁
完全理解Java中生產者和消費者模型.docx_第3頁
完全理解Java中生產者和消費者模型.docx_第4頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

生產者與消費者模型 在平時的編程中,經常遇到一個線程要產生數(shù)據(jù),而另一個線程要處理產生出來的數(shù)據(jù),這其實就是生產者和消費者的關系。生產者在產生數(shù)據(jù)后可以直接調用消費者處理數(shù)據(jù);也可以把數(shù)據(jù)放在一個緩沖區(qū)中,讓消費者從緩沖區(qū)中取出數(shù)據(jù)處理,兩種方式從調用方式上來說,第一種可是說是同步的,即生產者在生產出數(shù)據(jù)后要等待消費者消耗掉后才能生產下一個數(shù)據(jù),等待時間的長短取決于消費者處理數(shù)據(jù)的能力;第二種方式是異步的,生產者只管生產數(shù)據(jù),然后扔到一個緩沖區(qū)內,不管數(shù)據(jù)是否被立即處理了,消費者則從緩沖區(qū)中依次取出數(shù)據(jù)進行自己節(jié)奏的處理。從線程模型角度來說,第一種是單線程的,而第二種則是多線程的。多線程必須要考慮的一個問題是線程之間的協(xié)作,協(xié)作即協(xié)調合作,不要亂套,以生產者和消費者模型而言,就是當緩沖區(qū)里沒有數(shù)據(jù)時消費者要等待,等待生產者生產數(shù)據(jù),當緩沖區(qū)滿的時候生產者要等待,等待消費者消耗掉一些數(shù)據(jù)空出位置好存放數(shù)據(jù)。 java中為了實現(xiàn)多線程之間的協(xié)助,需要用到幾個特性:wait(),notify(),notifyAll(),synchronized,synchronized相當于操作系統(tǒng)里的臨界區(qū)或者鎖的概念,所謂臨界區(qū)就是說一次只能有一個線程進去,其他想進入的線程必須等待,加了synchronized鎖后,才能調用wait(),notify()和notifyAll()操作,wait方法被調用后,當前線程A(舉例)進入被加鎖對象的線程休息室,然后釋放鎖,等待被喚醒。釋放的鎖誰來獲取?當然是由先前等待的另一個線程B得到,B在獲得鎖后,進行某種操作后通過notify或者notifyAll把A從線程休息室喚醒,然后釋放鎖,A被喚醒后,重新獲取鎖定,進行下一語句的執(zhí)行。 再回到生產者和消費者模型,如果引入了緩沖區(qū)的話就需要處理生產者線程和消費者線程之間的協(xié)作,緩沖區(qū)可以有這幾種,隊列緩沖區(qū),比如隊列或者棧,隊列緩沖區(qū)的特點是其長度是動態(tài)增長的,這就意味著內存的動態(tài)分配帶來的性能開銷,同時隊列緩沖區(qū)還會產生因為多線程之間的同步和互斥帶來的開銷。環(huán)形緩沖區(qū)可以解決內存分配帶來開銷的問題,因為環(huán)形緩沖區(qū)長度是固定的。但是環(huán)形緩沖區(qū)還是無法解決同步互斥帶來的多線程切換的開銷,如果生產者和消費者都不止一個線程,帶來的開銷更大,終極解決辦法是引入雙緩沖區(qū),何為雙緩沖區(qū)?雙緩沖區(qū)顧名思義是有兩個長度固定的緩沖區(qū)A B,生產者和消費者只使用其中一個,當兩個緩沖區(qū)都操作完成后完成一次切換,開始時生產者開始向A里寫數(shù)據(jù),消費者從B里讀取數(shù)據(jù),當A寫滿同時B也讀完后,切換一下,這時消費者從A里取數(shù)據(jù),生產者向B寫數(shù)據(jù),由于生產者和消費者不會同時操作同一個緩沖區(qū),所以不會發(fā)生沖突。 生產者和消費者模型不止是用在多線程之間,不同進程之間也可以有。線程和進程到底有什么區(qū)別?這是很多程序員搞不清的問題,其實很簡單,進程有自己的地址空間和上下文,線程是在一個進程上并發(fā)執(zhí)行的代碼段。其實在win32系統(tǒng)中進程只是占用一定長度的地址空間,進程中總是有一個主線程來運行。消費者和生產者模型應用于進程間通信的典型例子是分布式消息處理,消息的消費者進程需要一個緩沖區(qū)緩沖收到的消息,消息的生產者進程也需要一個緩沖區(qū)緩沖將要發(fā)送的消息,這樣可以一定程度上減少因為網(wǎng)絡斷開引起的消息丟失。對于此模型,應該明確一下幾點:1, 生產者僅僅在倉儲未滿時生產,倉滿則停止生產。2, 消費 者僅僅在倉儲有產品時才能消費,倉空則等待。3, 當消費者發(fā)現(xiàn)倉儲沒有產品的時候會通知生產者生產。4, 生產者在生產出可消費產品的時候,應該通知等待的消費者去消費。以下是它的具體實現(xiàn): 1, public class ProducerConsumer 2, public static void main(String args) 3, SyncStack ss=new SyncStack();4, Producer p=new Producer(ss);5, Consumer c=new Consumer(ss);6, new Thread(p).start();7, new Thread(c).start();8, 9, 10,11, class WoTou 12, int id;13, WoTou(int id) 14, this.id=id;15, 16, public String toString() 17, return WoTou : +id;18, 19, 20,21, class SyncStack 22, int index=0;23, WoTou arrWT=new WoTou6;24, 25, public synchronized void push(WoTou wt) 26, while(index=arrWT.length) 27, try28, this.wait();29, catch(InterruptedException e) 30, e.printStackTrace();31, 32, 33, this.notify();34, arrWTindex=wt;35, index+;36, 37, 38, public synchronized WoTou pop() 39, while(index=0) 40, try41, this.wait();42, catch(InterruptedException e) 43, e.printStackTrace();44, 45, 46, this.notify();47, index-;48, return arrWTindex;49, 50, 51,52, class Producer implements Runnable 53, SyncStack ss=null;54, Producer(SyncStack ss) 55, this.ss=ss;56, 57, 58, public void run() 59, for(int i=0;i20;i+) 60, WoTou wt=new WoTou(i);61, ss.push(wt);62, System.out.println(生產了:+wt);63, try64, Thread.sleep(int)(Math.random()*2);65, catch(InterruptedException e) 66, e.printStackTrace();67, 68, 69, 70, 71,72, class Consumer implements Runnable 73, SyncStack ss=null;74, Consumer(SyncStack ss) 75, this.ss=ss;76, 77, 78, public void run() 79, for(int i=0;i20;i+) 80, WoTou wt=ss.pop();81, System.out.println(消費了:+wt);82, try83, Thread.sleep(int)(Math.random()*1000);84, catch(InterruptedException e) 85, e.printStackTrace();86, 87, 88, 89, 附:1程序、進程和線程程序,就是一段靜態(tài)的可執(zhí)行的代碼。進程,就是程序的一次動態(tài)的執(zhí)行過程。線程,是程序 從頭到尾的執(zhí)行路線,也稱為輕量級的進程。一個進程在執(zhí)行過程中,可以產生多個線程,形成多個執(zhí)行路線。但線程間是彼此相互獨立的。各個線程可以共享相同的內存空間,并利用共享內存來完成數(shù)據(jù)交換、實時通信和一些同步的工作。而進程都占有不同的內存空間。單線程是指一個 程序只有一條從開始到結束的順序的執(zhí)行路線。多線程是多個彼此獨立的線程,多條執(zhí)行路線。2.wait()、

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論