作者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://webptt.com/cn.aspx?n=bbs/java/M.1539474135.A.29B.html
1F:推 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
2F:推 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
3F:→ zop: 我的话,只会设计跑一个生产者的thread,每秒生产之後去检查 10/14 17:01
4F:→ zop: 消费者最早未结的需求,数量符合就结单,一直到数量不符,并 10/14 17:02
5F:→ zop: 且产生一个新的需求。 10/14 17:02
6F:→ obelisk0114: 消费者消费数量是随机的, 两者每秒都在行动 10/14 17:08
7F:→ obelisk0114: 只是生产的产品不够多, 消费者就需要等待 10/14 17:09
8F:→ zop: 制造跟购买中间,其实要多一个负责贩卖的 10/15 10:14
9F:→ obelisk0114: Clerk 程式是负责贩卖, 我觉得问题应该在它那边 10/15 12:49
用 BlockingQueue 可以得到结果, 但是只会有 Consumer 在 print
manufacture 只管生产,不去 print
这样应该不算两个 thread 都有 print ?
※ 编辑: obelisk0114 (47.148.240.220), 10/19/2018 14:33:48