无聊,想起还没自己实现过。写了个。备忘。
生产者&消费者问题描述
有一个生产者线程在生产产品,并放入仓库,另有一消费者线程从仓库中取出产品进行消费。
这个过程可以是无休止的,不能因为仓库已满生产者放不进产品而终止,也不能因为仓库中没有产品了消费者停止消费。
本例子采用使生产者与消费者之间的保持同步的方式实现此功能。当生产者生产的产品放入仓库时,会通知消费者可以进行消费了,如果放满了仓库则生产者暂时放弃自己的执行权,进入等待状态等待消费者消费产品;消费者从仓库中消费产品,如果发现仓库已空,则进入等待状态等待生产者生产新产品,并且每消费一件产品则通知生产者生产。
由程序最后的打印输出可看出,从“通知”到生产者/消费者真正执行生产/消费操作的时机也是不固定的。
下面是代码:
package lab.sodino.pc;
import java.util.LinkedList;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2012-7-24 下午04:25:47
*/
public class Sync {
/** 仓库。 */
private LinkedList<Goods> list;
/** 仓库最多存储10产品。 */
public static final int CAPABILITY = 10;
/** 限制只生产/消费100个产品,然后结束运行。 */
public static final int MAX_AMOUNT = 100;
public static void main(String[] args) {
Sync sync = new Sync();
sync.run();
}
public void run() {
list = new LinkedList<Goods>();
new Product().start();
new Consume().start();
}
/**
* 生产者:<br/>
* 1.负责生产产品;<br/>
* 2.生产出产品后负责通知消费者线程消费;<br/>
* 3.库存为MAX时,暂停生产;<br/>
* 4.每次只生产一件产品。<br/>
*/
class Product extends Thread {
int goodsIdx = 0;
public void run() {
try {
while (true) {
if (goodsIdx > MAX_AMOUNT) {
break;
}
synchronized (list) {
while (list.size() == CAPABILITY) {
if (list.size() == CAPABILITY) {
System.out.println("Product Goodses's Amount is full. wait");
// 等待消费者消费才有空间腾出给新生产的产品
list.wait();
}
}
Goods goods = new Goods(goodsIdx++);
if (list.add(goods)) {
System.out.println("Product new[" + String.valueOf(goods) + "]");
// 通知消费者消费
list.notify();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 消费者:<br/>
* 1.一次只消费一个产品;<br/>
* 2.消费完产品后负责通知生产者继续生产。<br/>
* */
class Consume extends Thread {
public void run() {
try {
while (true) {
synchronized (list) {
while (list.size() == 0) {
System.out.println("Consume There's no goods,wait...");
// 等待生产者生产
list.wait();
}
Goods goods = list.remove(0);
System.out.println("Consume remove[" + String.valueOf(goods) + "]");
if (goods.getIndex() < MAX_AMOUNT) {
// 通知生产者继续生产
list.notify();
} else {
System.out.println("List.size=" + list.size());
break;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package lab.sodino.pc;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2012-7-24 下午04:25:47
*/
public class Goods {
private int index;
public Goods(int idx) {
index = idx;
}
public int getIndex() {
return index;
}
public String toString() {
String line = "Goods id:" + Integer.toString(index);
return line;
}
}
输出:
Consume There's no goods,wait...
Product new[Goods id:0]
Consume remove[Goods id:0]
Consume There's no goods,wait...
Product new[Goods id:1]
Consume remove[Goods id:1]
Consume There's no goods,wait...
Product new[Goods id:2]
Consume remove[Goods id:2]
Consume There's no goods,wait...
Product new[Goods id:3]
Consume remove[Goods id:3]
Consume There's no goods,wait...
Product new[Goods id:4]
Consume remove[Goods id:4]
Consume There's no goods,wait...
Product new[Goods id:5]
Consume remove[Goods id:5]
Consume There's no goods,wait...
Product new[Goods id:6]
Consume remove[Goods id:6]
Consume There's no goods,wait...
Product new[Goods id:7]
Consume remove[Goods id:7]
Consume There's no goods,wait...
Product new[Goods id:8]
Consume remove[Goods id:8]
Consume There's no goods,wait...
Product new[Goods id:9]
Consume remove[Goods id:9]
Consume There's no goods,wait...
Product new[Goods id:10]
Product new[Goods id:11]
Product new[Goods id:12]
Product new[Goods id:13]
Product new[Goods id:14]
Product new[Goods id:15]
Product new[Goods id:16]
Product new[Goods id:17]
Product new[Goods id:18]
Product new[Goods id:19]
Product Goodses's Amount is full. wait
Consume remove[Goods id:10]
Consume remove[Goods id:11]
Consume remove[Goods id:12]
Consume remove[Goods id:13]
Consume remove[Goods id:14]
Consume remove[Goods id:15]
Consume remove[Goods id:16]
Consume remove[Goods id:17]
Consume remove[Goods id:18]
Consume remove[Goods id:19]
Consume There's no goods,wait...
Product new[Goods id:20]
Product new[Goods id:21]
Product new[Goods id:22]
Product new[Goods id:23]
Product new[Goods id:24]
Product new[Goods id:25]
Product new[Goods id:26]
Product new[Goods id:27]
Product new[Goods id:28]
Product new[Goods id:29]
Product Goodses's Amount is full. wait
Consume remove[Goods id:20]
Consume remove[Goods id:21]
Consume remove[Goods id:22]
Consume remove[Goods id:23]
Consume remove[Goods id:24]
Consume remove[Goods id:25]
Consume remove[Goods id:26]
Consume remove[Goods id:27]
Consume remove[Goods id:28]
Consume remove[Goods id:29]
Consume There's no goods,wait...
Product new[Goods id:30]
Product new[Goods id:31]
Product new[Goods id:32]
Product new[Goods id:33]
Product new[Goods id:34]
Product new[Goods id:35]
Product new[Goods id:36]
Product new[Goods id:37]
Product new[Goods id:38]
Product new[Goods id:39]
Product Goodses's Amount is full. wait
Consume remove[Goods id:30]
Consume remove[Goods id:31]
Consume remove[Goods id:32]
Consume remove[Goods id:33]
Consume remove[Goods id:34]
Consume remove[Goods id:35]
Consume remove[Goods id:36]
Consume remove[Goods id:37]
Consume remove[Goods id:38]
Consume remove[Goods id:39]
Consume There's no goods,wait...
Product new[Goods id:40]
Product new[Goods id:41]
Product new[Goods id:42]
Product new[Goods id:43]
Product new[Goods id:44]
Product new[Goods id:45]
Product new[Goods id:46]
Product new[Goods id:47]
Product new[Goods id:48]
Product new[Goods id:49]
Product Goodses's Amount is full. wait
Consume remove[Goods id:40]
Consume remove[Goods id:41]
Consume remove[Goods id:42]
Consume remove[Goods id:43]
Consume remove[Goods id:44]
Consume remove[Goods id:45]
Consume remove[Goods id:46]
Consume remove[Goods id:47]
Consume remove[Goods id:48]
Consume remove[Goods id:49]
Consume There's no goods,wait...
Product new[Goods id:50]
Product new[Goods id:51]
Product new[Goods id:52]
Product new[Goods id:53]
Product new[Goods id:54]
Product new[Goods id:55]
Product new[Goods id:56]
Product new[Goods id:57]
Product new[Goods id:58]
Product new[Goods id:59]
Product Goodses's Amount is full. wait
Consume remove[Goods id:50]
Consume remove[Goods id:51]
Consume remove[Goods id:52]
Product new[Goods id:60]
Product new[Goods id:61]
Product new[Goods id:62]
Product Goodses's Amount is full. wait
Consume remove[Goods id:53]
Consume remove[Goods id:54]
Consume remove[Goods id:55]
Consume remove[Goods id:56]
Consume remove[Goods id:57]
Consume remove[Goods id:58]
Consume remove[Goods id:59]
Consume remove[Goods id:60]
Consume remove[Goods id:61]
Consume remove[Goods id:62]
Consume There's no goods,wait...
Product new[Goods id:63]
Product new[Goods id:64]
Product new[Goods id:65]
Product new[Goods id:66]
Product new[Goods id:67]
Product new[Goods id:68]
Product new[Goods id:69]
Product new[Goods id:70]
Product new[Goods id:71]
Product new[Goods id:72]
Product Goodses's Amount is full. wait
Consume remove[Goods id:63]
Consume remove[Goods id:64]
Consume remove[Goods id:65]
Consume remove[Goods id:66]
Consume remove[Goods id:67]
Consume remove[Goods id:68]
Consume remove[Goods id:69]
Consume remove[Goods id:70]
Consume remove[Goods id:71]
Consume remove[Goods id:72]
Consume There's no goods,wait...
Product new[Goods id:73]
Product new[Goods id:74]
Product new[Goods id:75]
Product new[Goods id:76]
Product new[Goods id:77]
Product new[Goods id:78]
Product new[Goods id:79]
Product new[Goods id:80]
Product new[Goods id:81]
Product new[Goods id:82]
Product Goodses's Amount is full. wait
Consume remove[Goods id:73]
Consume remove[Goods id:74]
Product new[Goods id:83]
Product new[Goods id:84]
Product Goodses's Amount is full. wait
Consume remove[Goods id:75]
Consume remove[Goods id:76]
Consume remove[Goods id:77]
Consume remove[Goods id:78]
Consume remove[Goods id:79]
Consume remove[Goods id:80]
Consume remove[Goods id:81]
Consume remove[Goods id:82]
Consume remove[Goods id:83]
Consume remove[Goods id:84]
Consume There's no goods,wait...
Product new[Goods id:85]
Product new[Goods id:86]
Product new[Goods id:87]
Product new[Goods id:88]
Product new[Goods id:89]
Product new[Goods id:90]
Product new[Goods id:91]
Product new[Goods id:92]
Product new[Goods id:93]
Product new[Goods id:94]
Product Goodses's Amount is full. wait
Consume remove[Goods id:85]
Product new[Goods id:95]
Product Goodses's Amount is full. wait
Consume remove[Goods id:86]
Consume remove[Goods id:87]
Consume remove[Goods id:88]
Consume remove[Goods id:89]
Consume remove[Goods id:90]
Consume remove[Goods id:91]
Product new[Goods id:96]
Product new[Goods id:97]
Product new[Goods id:98]
Product new[Goods id:99]
Product new[Goods id:100]
Consume remove[Goods id:92]
Consume remove[Goods id:93]
Consume remove[Goods id:94]
Consume remove[Goods id:95]
Consume remove[Goods id:96]
Consume remove[Goods id:97]
Consume remove[Goods id:98]
Consume remove[Goods id:99]
Consume remove[Goods id:100]
List.size=0