作者obelisk0114 (追風箏的孩子)
看板java
標題[問題] 多執行續的消費者和生產者
時間Sun Oct 14 07:41:59 2018
生產者每秒可以生產一樣產品 (product),
消費者每秒消費 0, 1, 2..., m 樣產品 (order)
若生產者來不及生產, 消費者必須等待
消費者一次買完所需, 除非產品不夠 (process)
ex1: 產品 4, 消費 2 => 產品 2
ex2: T1 消費 2
T2 產品 1, 完成 1
T2 產品 1, 完成 1
T1 消費 1 (新的)
T2 產品 1, 完成 1 (處理新的 T1)
我需要列印前 n 秒結果
主要程式1 Clerk
private int product = 0;
private int order = 0;
private int process = 0;
// Manufacture
public synchronized void setProduct() {
product++;
process = Math.min(product, order);
order -= process;
System.out.printf("%d car available, %d requests processed!\n",
product, process);
product -= process;
if (order == 0) {
notify();
}
n--;
if (n == 0) { // 感覺是不好的寫法
System.exit(0);
}
}
// Consumer
public synchronized void getProduct(int size) {
System.out.printf("%d orders received\n", size);
order = size;
if (product + 1 < size) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
主要程式2 Consumer
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
public void run() {
System.out.println("ready to take orders..");
for (int i = 1; i <= n; i++) {
try {
Thread.sleep(1000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
int size = (int) (Math.random() * (m + 1));
clerk.getProduct(size);
}
}
主要程式3 Manufacture
private Clerk clerk;
public Manufacture(Clerk clerk) {
this.clerk = clerk;
}
public void run() {
System.out.println("ready to manufacture cars..");
for (int i = 1; i <= n; i++) {
try {
Thread.sleep(1000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
clerk.setProduct();
}
}
Bug:
有時會產生奇怪的結果,下面是其中一次的結果
ready to take orders..
ready to manufacture cars..
1 orders received
1 car available, 1 requests processed!
1 car available, 0 requests processed! (應該要先 orders)
0 orders received
2 car available, 0 requests processed!
0 orders received
3 car available, 0 requests processed!
2 orders received
4 car available, 2 requests processed!
0 orders received
3 car available, 0 requests processed!
0 orders received
4 car available, 0 requests processed!
0 orders received
5 car available, 0 requests processed!
1 orders received
2 orders received
6 car available, 2 requests processed! (順序又反轉了)
5 car available, 0 requests processed!
請各位大大看看要如何修改
謝謝
--
│ ███ ▂▄▃
││││
│ ˋ ◤Mooncat~◥││││ 「為什麼
,
│ ‵ ◤ ◥▏*_▂▁ ▋
│││ 為什麼教授這麼靠盃
│ ′ 、▌█
▊▉▏ │ 沒天理啊
……
…」
◢ ◤◢
◣▋◢ █
▋▊ ▕▅▇
◥◥*Mooncat~
◢ ▂▇ˋ█▆◤
▂_ ▁▄▆▇▃ by mooncats
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 47.148.240.220
※ 文章網址: https://www.ptt.cc/bbs/java/M.1539474135.A.29B.html
推 swpoker: 程式進入點勒,main?要貼完整程式碼好嗎 10/14 08:48
public class Sales {
public static void main(String[] args) {
Clerk clerk = new Clerk();
// Consumer
Thread consumerThread = new Thread(new Consumer(clerk));
// Manufacture
Thread producerThread = new Thread(new Manufacture(clerk));
consumerThread.start();
producerThread.start();
}
}
※ 編輯: obelisk0114 (47.148.240.220), 10/14/2018 08:58:42
推 swpoker: order檢查要放在前面啊 10/14 10:22
將 Clerk 的 setProduct 改成以下
public synchronized void setProduct() {
if (order == 0) {
notify();
}
product++;
process = Math.min(product, order);
order -= process;
System.out.printf("%d car available, %d requests processed!\n",
product, process);
product -= process;
n--;
if (n == 0) {
System.exit(0);
}
}
也會出現下面
ready to take orders..
ready to manufacture cars..
1 car available, 0 requests processed!
1 orders received
2 car available, 1 requests processed!
2 orders received
2 car available, 2 requests processed!
1 orders received
1 car available, 1 requests processed!
2 orders received
1 car available, 1 requests processed!
1 car available, 1 requests processed!
1 car available, 0 requests processed!
2 car available, 0 requests processed!
2 orders received
1 orders received
3 car available, 1 requests processed!
3 car available, 0 requests processed!
※ 編輯: obelisk0114 (47.148.240.220), 10/14/2018 17:04:12
→ zop: 我的話,只會設計跑一個生產者的thread,每秒生產之後去檢查 10/14 17:01
→ zop: 消費者最早未結的需求,數量符合就結單,一直到數量不符,並 10/14 17:02
→ zop: 且產生一個新的需求。 10/14 17:02
→ obelisk0114: 消費者消費數量是隨機的, 兩者每秒都在行動 10/14 17:08
→ obelisk0114: 只是生產的產品不夠多, 消費者就需要等待 10/14 17:09
→ zop: 製造跟購買中間,其實要多一個負責販賣的 10/15 10:14
→ obelisk0114: Clerk 程式是負責販賣, 我覺得問題應該在它那邊 10/15 12:49
用 BlockingQueue 可以得到結果, 但是只會有 Consumer 在 print
manufacture 只管生產,不去 print
這樣應該不算兩個 thread 都有 print ?
※ 編輯: obelisk0114 (47.148.240.220), 10/19/2018 14:33:48