日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

线程---生产者消费者问题

發布時間:2025/3/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程---生产者消费者问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在開始之前先簡單回顧一下生產者消費者問題:一群生產者在生產消息,并將此消息提供給消費者去消費。它們中間設了具有N個緩存區的緩沖池,生產者每次可將生產的消息放入一個緩存區內,消費者每次可將一個緩存區內的消息拿出來消費。但這個過程有兩個條件:任何一方操作一個緩沖區時不能有其它同時對該緩沖區進行操作;只有當緩沖區還有空余,生產者才能生產,只有當緩沖區至少有一個產品,消費者才能從中取出來消費。這里兩個條件分別對應了互斥和同步。


生產者與消費者模型中,要保證以下幾點:
1 同一時間內只能有一個生產者生產
2 同一時間內只能有一個消費者消費
3 生產者生產的同時消費者不能消費
4 消息隊列滿時生產者不能繼續生產
5 消息隊列空時消費者不能繼續消費


[b]正文:[/b]

首先先建一個使用多線程的寫的生產者消費者的通用類,在生產方法中(produce()),如果隊列中已經有五個大餅,就提示消息,等待消費者消費大餅,否則往隊列中添加大餅。在消費方法中(consume()),如果隊列中沒有大餅,則提示消息,等待生產者生產大餅,否則就刪除一條大餅消息。
import java.util.ArrayList;
import java.util.List;

public class Stack {
List<Message> stack = new ArrayList<Message>();
private int MAX_MESSAGE_NUM = 5;
public Stack(){
System.out.println("大餅生產基地!");
}

//加上互斥鎖
public synchronized void produce(Message message){
while( stack.size() == MAX_MESSAGE_NUM ){
try{
System.out.println(Thread.currentThread().getName() + " 隊列滿!等待消費...");
this.wait();
}catch(InterruptedException e){
}
}
stack.add(message);
System.out.println(Thread.currentThread().getName() + " 正在生產" + message.getContent() + " 當前大餅個數:" + stack.size());
this.notify();
}

//加上互斥鎖
public synchronized void consume(){
while(stack.size() == 0){
try{
System.out.println("隊列空,無大餅,請等待...");
this.wait();
}catch(InterruptedException e){
}
}
Message message = stack.get(0);
stack.remove(0);
System.out.println(Thread.currentThread().getName() + " 正在消費"
+ message.getContent() + " ,當前大餅個數: " + stack.size());

this.notify();
}

}

創建個消息對象。
public class Message {
public static int id;
public String content;
public static int getId() {
return id;
}
public static void setId(int id) {
Message.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}

}

生產者類,主要產生消息,注意繼承了Thread并實現了run,并且有一個對Stack實例的引用,主要調用了Stack的produce方法
class Producer extends Thread {

private Stack stack;

public Producer(Stack s){
this.stack = s;
}

public void run (){
while(true){
Message message = new Message();
message.setId(++ Message.id);
message.setContent("大餅" + Message.id);

stack.produce(message);
try{
sleep(100);
}catch(Exception e){

}
}
}
}

消費者類,主要消費消息,跟生產者是對稱的,主要調用了Stack的consume方法。
class Consumer extends Thread {
private Stack stack;

Consumer(Stack stack) {
this.stack = stack;
}

public void run() {
while (true) {
stack.consume();
try {
sleep(100);
} catch (Exception e) {
}

}
}
}

主類,主要構造出一個Stack并啟動N個生產者和消費者。

public class ThreadTest {

public static void main(String[] args) {

Stack s = new Stack();

Producer p1 = new Producer(s);
Producer p2 = new Producer(s);
Producer p3 = new Producer(s);

Consumer c1 = new Consumer(s);
Consumer c2 = new Consumer(s);
Consumer c3 = new Consumer(s);

Thread threadP1 = new Thread(p1, "thread-生產者--A");
Thread threadP2 = new Thread(p2, "thread-生產者--B");
Thread threadP3 = new Thread(p3, "thread-生產者--C");

Thread threadC1 = new Thread(c1, "thread-消費者甲");
Thread threadC2 = new Thread(c2, "thread-消費者乙");
Thread threadC3 = new Thread(c3, "thread-消費者丙");

threadP1.start();
threadP2.start();
threadP3.start();

threadC1.start();
threadC2.start();
//threadC3.start();
}
}

從以上這個例子,可以看出來,通過一個Stack,我們將一個對象的創建和執行分離開了(在生產者中創建,在消費者中執行,這種分離帶來了極大的好處。比如將費時的執行分開之后提高了創建線程的響應性,并且它們之間的順序實現了可控性,不用創建完了馬上就執行,它們的分離使得可以分布式做創建和分離,從而出現了類似BMQ的消息中間件。

總結

以上是生活随笔為你收集整理的线程---生产者消费者问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。