當前位置:首頁 » 編程語言 » java的生產者消費者

java的生產者消費者

發布時間: 2022-05-08 18:56:23

1. java線程生產者消費者問題

你的消費者線程先啟動的,因為index==0,所以進入了等待模式,而生產者線程沒有在push了之後進行喚醒,導致了問題。
測試在push方法中的index++後面添加notifyAll()方法可以解決該問題:
index++;
this.notifyAll();
Thread-1生產了1號饅頭
Thread-0消費了第1個饅頭
Thread-1生產了2號饅頭
Thread-0消費了第2個饅頭
Thread-1生產了3號饅頭
Thread-0消費了第3個饅頭
Thread-1生產了4號饅頭
Thread-0消費了第4個饅頭
Thread-1生產了5號饅頭
Thread-0消費了第5個饅頭
Thread-1生產了6號饅頭
Thread-0消費了第6個饅頭
Thread-1生產了7號饅頭
Thread-0消費了第7個饅頭
Thread-1生產了8號饅頭
Thread-0消費了第8個饅頭
Thread-1生產了9號饅頭
Thread-0消費了第9個饅頭

2. java 生產者消費者是設計模式嗎

對於多線程程序來說,不管任何編程語言,生產者和消費者模型都是最經典的。就像學習每一門編程語言一 樣,Hello World!都是最經典的例子。
實際上,准確說應該是「生產者-消費者-倉儲」模型,離開了倉儲,生產者消費者模型就顯得沒有說服力了。
對於此模型,應該明確一下幾點:
1、生產者僅僅在倉儲未滿時候生產,倉滿則停止生產。
2、消費者僅僅在倉儲有產品時候才能消費,倉空則等待。
3、當消費者發現倉儲沒產品可消費時候會通知生產者生產。
4、生產者在生產出可消費產品時候,應該通知等待的消費者去消費。
此模型將要結合java.lang.Object的wait與notify、notifyAll方法來實現以上的需求。這是非常重要的。

3. JAVA模擬生產者與消費者實例

使用的生產者和消費者模型具有如下特點:
(1)本實驗的多個緩沖區不是環形循環的,也不要求按順序訪問。生產者可以把產品放到目前某一個空緩沖區中。
(2)消費者只消費指定生產者的產品。
(3)在測試用例文件中指定了所有的生產和消費的需求,只有當共享緩沖區的數據滿足了所有關於它的消費需求後,此共享緩沖區才可以作為空閑空間允許新的生產者使用。
(4)本實驗在為生產者分配緩沖區時各生產者間必須互斥,此後各個生產者的具體生產活動可以並發。而消費者之間只有在對同一產品進行消費時才需要互斥,同時它們在消費過程結束時需要判斷該消費對象是否已經消費完畢並清除該產品。
Windows
用來實現同步和互斥的實體。在Windows
中,常見的同步對象有:信號量(Semaphore)、
互斥量(Mutex)、臨界段(CriticalSection)和事件(Event)等。本程序中用到了前三個。使用這些對象都分
為三個步驟,一是創建或者初始化:接著請求該同步對象,隨即進入臨界區,這一步對應於互斥量的
上鎖;最後釋放該同步對象,這對應於互斥量的解鎖。這些同步對象在一個線程中創建,在其他線程
中都可以使用,從而實現同步互斥。當然,在進程間使用這些同步對象實現同步的方法是類似的。
1.用鎖操作原語實現互斥
為解決進程互斥進人臨界區的問題,可為每類臨界區設置一把鎖,該鎖有打開和關閉兩種狀態,進程執行臨界區程序的操作按下列步驟進行:
①關鎖。先檢查鎖的狀態,如為關閉狀態,則等待其打開;如已打開了,則將其關閉,繼續執行步驟②的操作。
②執行臨界區程序。
③開鎖。將鎖打開,退出臨界區。
2.信號量及WAIT,SIGNAL操作原語
信號量的初值可以由系統根據資源情況和使用需要來確定。在初始條件下信號量的指針項可以置為0,表示隊列為空。信號量在使用過程中它的值是可變的,但只能由WAIT,SIGNAL操作來改變。設信號量為S,對S的WAIT操作記為WAIT(S),對它的SIGNAL操作記為SIGNAL(S)。
WAIT(S):順序執行以下兩個動作:
①信號量的值減1,即S=S-1;
②如果S≥0,則該進程繼續執行;
如果
S(0,則把該進程的狀態置為阻塞態,把相應的WAITCB連人該信號量隊列的末尾,並放棄處理機,進行等待(直至其它進程在S上執行SIGNAL操作,把它釋放出來為止)。
SIGNAL(S):順序執行以下兩個動作
①S值加
1,即
S=S+1;
②如果S)0,則該進程繼續運行;
如果S(0則釋放信號量隊列上的第一個PCB(既信號量指針項所指向的PCB)所對應的進程(把阻塞態改為就緒態),執行SIGNAL操作的進程繼續運行。
在具體實現時注意,WAIT,SIGNAL操作都應作為一個整體實施,不允許分割或相互穿插執行。也就是說,WAIT,SIGNAL操作各自都好像對應一條指令,需要不間斷地做下去,否則會造成混亂。
從物理概念上講,信號量S)時,S值表示可用資源的數量。執行一次WAIT操作意味著請求分配一個單位資源,因此S值減1;當S<0時,表示已無可用資源,請求者必須等待別的進程釋放了該類資源,它才能運行下去。所以它要排隊。而執行一次SIGNAL操作意味著釋放一個單位資源,因此S值加1;若S(0時,表示有某些進程正在等待該資源,因而要把隊列頭上的進程喚醒,釋放資源的進程總是可以運行下去的。
---------------
/**
*
生產者
*
*/
public
class
Procer
implements
Runnable{
private
Semaphore
mutex,full,empty;
private
Buffer
buf;
String
name;
public
Procer(String
name,Semaphore
mutex,Semaphore
full,Semaphore
empty,Buffer
buf){
this.mutex
=
mutex;
this.full
=
full;
this.empty
=
empty;
this.buf
=
buf;
this.name
=
name;
}
public
void
run(){
while(true){
empty.p();
mutex.p();
System.out.println(name+"
inserts
a
new
proct
into
"+buf.nextEmptyIndex);
buf.nextEmptyIndex
=
(buf.nextEmptyIndex+1)%buf.size;
mutex.v();
full.v();
try
{
Thread.sleep(1000);
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
}
---------------
/**
*
消費者
*
*/
public
class
Customer
implements
Runnable{
private
Semaphore
mutex,full,empty;
private
Buffer
buf;
String
name;
public
Customer(String
name,Semaphore
mutex,Semaphore
full,Semaphore
empty,Buffer
buf){
this.mutex
=
mutex;
this.full
=
full;
this.empty
=
empty;
this.buf
=
buf;
this.name
=
name;
}
public
void
run(){
while(true){
full.p();
mutex.p();
System.out.println(name+"
gets
a
proct
from
"+buf.nextFullIndex);
buf.nextFullIndex
=
(buf.nextFullIndex+1)%buf.size;
mutex.v();
empty.v();
try
{
Thread.sleep(1000);
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
}
-------------------------
/**
*
緩沖區
*
*/
public
class
Buffer{
public
Buffer(int
size,int
nextEmpty,int
nextFull){
this.nextEmptyIndex
=
nextEmpty;
this.nextFullIndex
=
nextFull;
this.size
=
size;
}
public
int
size;
public
int
nextEmptyIndex;
public
int
nextFullIndex;
}
-----------------
/**
*
此類用來模擬信號量
*
*/
public
class
Semaphore{
private
int
semValue;
public
Semaphore(int
semValue){
this.semValue
=
semValue;
}
public
synchronized
void
p(){
semValue--;
if(semValue<0){
try
{
this.wait();
}
catch
(InterruptedException
e)
{
e.printStackTrace();
}
}
}
public
synchronized
void
v(){
semValue++;
if(semValue<=0){
this.notify();
}
}
}
------------------------
public
class
Test
extends
Thread
{
public
static
void
main(String[]
args)
{
Buffer
bf=new
Buffer(10,0,0);
Semaphore
mutex=new
Semaphore(1);
Semaphore
full=new
Semaphore(0);
Semaphore
empty=new
Semaphore(10);
//new
Thread(new
Procer("p001",mutex,full,empty,bf)).start();
Procer
p=new
Procer("p001",mutex,full,empty,bf);
new
Thread(new
Procer("p002",mutex,full,empty,bf)).start();
new
Thread(new
Procer("p003",mutex,full,empty,bf)).start();
new
Thread(new
Procer("p004",mutex,full,empty,bf)).start();
new
Thread(new
Procer("p005",mutex,full,empty,bf)).start();
try{
sleep(3000);
}
catch(Exception
ex)
{
ex.printStackTrace();
}
new
Thread(new
Customer("c001",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c002",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c003",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c004",mutex,full,empty,bf)).start();
new
Thread(new
Customer("c005",mutex,full,empty,bf)).start();
}
}
--------------------------------------------

4. JAVA生產者,消費者問題

確實在生產者和消費者之間進行了同步,但是在各自線程的run()方法中列印的內容和put,get操作無關所以無法保持同步,導致了輸出結果混亂,另外消費者線程的run方法也要作適當修改,這里讓他在接受到最後一個字元『e』後暫停一秒終止,代碼如下:
class app15
{
private char ch;
public volatile boolean available = false;

synchronized char get()
{
while (available == false)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
available = false;
notify();
System.out.println("接受到的數據是: "+ch);
return ch;
}

synchronized void put(char newch)
{
while (available == true)
{
try
{
wait();
}
catch (InterruptedException e)
{
}
}
ch = newch;
available = true;
System.out.println("生產的數據是:" + ch);
notify();
}

public static void main(String args[])
{
app15 comn = new app15();
procer p = new procer(comn);
consumer c = new consumer(comn);
p.start();
c.start();
}
}

class procer extends Thread
{
private app15 comn;

public procer(app15 thiscomn)
{
comn = thiscomn;
}

public void run()
{
char c;
for (c = 'a'; c <= 'e'; c++)
{

comn.put(c);

}
}
}

class consumer extends Thread
{
private app15 comn;

public consumer(app15 thiscomn)
{
comn = thiscomn;
}

public void run()
{
while(true)
{
if(comn.get()=='e')
{
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
break;
}

}
}
}

5. java 生產者 消費者問題

這個很好解釋。
生產0消費0後,生產者生產了1後,
b.pull(sb);//這一塊執行完,cup的時間被消費者,消費消費後列印出消費了1。然後生產者線程才又搶到執行時間。執行這一句。
System.out.println( 生產了+ sb);
為什麼會這樣,因為你兩個線程的run方法沒有互斥。
你如果將列印語句放在SteamedBun sb = b.pop();
pop()方法內部執行就行了。

6. java 怎樣測試生產者消費者

這個主要涉及到線程相關的東西。一個類用於生產(Proct),一個類用於賣出(Customer),再加一個用於存儲的類(Data)。理清他們之間的邏輯。生產以及賣出的時候最好用一個標示來表明Data中的數量是否允許繼續生產或者賣出。

7. java實現生產者和消費者問題的幾種方式

生產者消費者問題是多線程的一個經典問題,它描述是有一塊緩沖區作為倉庫,生產者可以將產品放入倉庫,消費者則可以從倉庫中取走產品。
解決生產者/消費者問題的方法可分為兩類:
採用某種機制保護生產者和消費者之間的同步;
在生產者和消費者之間建立一個管道。
第一種方式有較高的效率,並且易於實現,代碼的可控制性較好,屬於常用的模式。第二種管道緩沖區不易控制,被傳輸數據對象不易於封裝等,實用性不強。
在Java中有四種方法支持同步,其中前三個是同步方法,一個是管道方法。
wait()
/
notify()方法
await()
/
signal()方法
BlockingQueue阻塞隊列方法
PipedInputStream
/
PipedOutputStream
通過
wait()
/
notify()方法實現:
wait()
/
nofity()方法是基類Object的兩個方法:
wait()方法:當緩沖區已滿/空時,生產者/消費者線程停止自己的執行,放棄鎖,使自己處於等等狀態,讓其他線程執行。
notify()方法:當生產者/消費者向緩沖區放入/取出一個產品時,向其他等待的線程發出可執行的通知,同時放棄鎖,使自己處於等待狀態。
通過await()
/
signal()方法實現:
await()和signal()的功能基本上和wait()
/
nofity()相同,完全可以取代它們,但是它們和新引入的鎖定機制Lock直接掛鉤,具有更大的靈活性。通過在Lock對象上調用newCondition()方法,將條件變數和一個鎖對象進行綁定,進而控制並發程序訪問競爭資源的安全。
通過BlockingQueue方法實現:
它是一個已經在內部實現了同步的隊列,實現方式採用的是我們第2種await()
/
signal()方法。它可以在生成對象時指定容量大小。它用於阻塞操作的是put()和take()方法:
put()方法:類似於我們上面的生產者線程,容量達到最大時,自動阻塞。
take()方法:類似於我們上面的消費者線程,容量為0時,自動阻塞。

8. java 生產者與消費者 的簡單問題

1 toString是在控制台列印對象的時候會調用的對象的方法。。比如你定義個Sx對象sx。。然後System.out.println(sx);就會先調用sx的toString方法。。將得到的String對象列印在控制台。。每個類都繼承自Object。。Object類裡面有個toString方法。。返回的是該對象在內存中的地址。。如果你不重寫這個方法。。列印出來的東西你看不明白的。。
2 java中數據類型有基本類型(int那些)和引用類型(就是所謂的對象)。。java中數組是對象。。每個數組對象都有一個length屬性。。值是這個數組的元素個數。。對象調用屬性是不需要括弧的。。方法才需要。。
3 kuang ss=null;就是定義一個kuang對象ss。。其初始值為null。。為null的對象在內存中什麼都沒有
int index=0; Wotou[] tou=new Wotou[6];這兩個都不是為空的。。都有具體的初始值。。
4 Wotou wt=ss.pop();表示定義一個Wotou對象wt。。並將調用ss對象的pop方法的返回值賦值給wt對象。。具體你看下kuang 類的pop方法就知道了。。

9. java中生產者消費者的問題

食人花其實是大花草。因為花的直徑很大又加上花體本身會散發出一種腐爛的屍臭味。所以讓人以為他會吃人。才會有食人花這個名字的由來。其實食人花差不多值得是食蟲植物(食肉植物)。食肉植物能將捕獲的動物分解,這個過程類似動物的消化過程。分解的最終產物,尤其是氮的化合物及鹽類為植物所吸收。食肉植物多數能進行光合作用,又能消化動物蛋白質,能適應極端的環境。因此它既是生產者也是消費者。

手機看島國電影 進酷影模式,看片沒廣告,啥資源都有

10. java多生產者和多消費者

public static void main(String[] args) {
Buffer buffer=new Buffer(); //創建一個臨界區對象
new Procer(buffer,100).start(); //創建一個生產者對象,並啟動其線程
new Consumer(buffer,200).start(); //創建一個消費者對象,並啟動其線程
new Consumer(buffer,201).start(); //創建第二個消費者對象,並啟動其線程
}

這一段代碼,多加入
new Consumer(buffer,201).start(); //創建第二個消費者對象,並啟動其線程
多加一段代碼創建一個消費者
多加入
new Procer(buffer,100).start();
創建一個生產者。
想要很多生產者和消費者?加就是了啊。

第四個文件 Buffer.java
這個是實現同步的主要緩存類。想要實現同步
在每個方法的聲明前都加入synchronized 就行
synchronized 線程鎖,很好用的。源代碼已經加入了
就比如
public synchronized void put(int value) { //同步方法控制臨界區內容寫入

熱點內容
手機店設置的初始密碼一般是多少 發布:2025-05-11 09:33:15 瀏覽:400
昂科威選擇哪個配置 發布:2025-05-11 09:25:50 瀏覽:35
怎麼解決安卓視頻全屏卡頓 發布:2025-05-11 09:14:55 瀏覽:725
匯編從編譯到執行 發布:2025-05-11 09:09:04 瀏覽:257
安卓系統低版本如何升級 發布:2025-05-11 09:04:44 瀏覽:251
認證類型加密演算法 發布:2025-05-11 08:58:35 瀏覽:561
android停靠 發布:2025-05-11 08:42:23 瀏覽:645
超時代加密 發布:2025-05-11 08:41:29 瀏覽:780
為什麼還要輸入支取密碼 發布:2025-05-11 08:32:24 瀏覽:362
資料庫課程設計案例 發布:2025-05-11 08:15:33 瀏覽:51