生产者和消费者问题中锁定的问题?

moon197896 2009-07-25 12:06:05

public class ManufactureConsume {
public static void main(String[] args) {
CommodityStack cs = new CommodityStack();
Manufacture m = new Manufacture(cs);
Consumer c = new Consumer(cs);
//new Thread(m).start();
new Thread(m).start();
new Thread(m).start();
new Thread(c).start();

}
}
class Commodity {
public int id = 0;
Commodity (int id) {
this.id = id;
}
public String toString() {
return "Commodity:" + id;
}
}
class CommodityStack {
static int index = 0;
static Commodity[] c = new Commodity[6];
public synchronized void push (Commodity cd) {
while (index == c.length) {
try{
this.wait();
}catch (InterruptedException e) {}
}
this.notifyAll();
c[index] = cd;
index++;
}
public synchronized Commodity pop () {
while (index == 0) {
try{
this.wait();
}catch (InterruptedException e) {}
}
this.notifyAll();
index--;
return c[index];
}
}
class Manufacture implements Runnable {
CommodityStack cs = null;
Manufacture (CommodityStack cs) {
this.cs = cs;
}
public void run() {
for (int i = 0; i < 10; i++) {
Commodity cd = new Commodity(cs.index);
cs.push(cd);
System.out.println("制造" + cd);
try {
Thread.sleep(300);
} catch (InterruptedException e ) {}
}
}
}
class Consumer implements Runnable {
CommodityStack cs = null;
Consumer (CommodityStack cs) {
this.cs = cs;
}
public void run() {
while (cs.index != 0) {
System.out.println("吃掉了" + cs.pop());
try {
Thread.sleep(200);
} catch (InterruptedException e ) {}
}
}
}


问题是,在实际运行中,会出现同生产了两个同样ID的Commodity。也会出现同时消费了两个相同ID的Commodity的问题。

也就是说,会出现一下的输出:

制造Commodity:3
制造Commodity:3
制造Commodity:4
吃掉了Commodity:4
制造Commodity:4
吃掉了Commodity:4
吃掉了Commodity:3
吃掉了Commodity:3


这种情况是不是意味着生产和消费进程未能被独占锁定。有什么方法可以解决呢?
...全文
125 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Miracle1216 2009-07-29
  • 打赏
  • 举报
回复
太长了,都不想看。。。
  • 打赏
  • 举报
回复
给你贴一个生产-消费者的例子,是《java编程思想》上的例子,应该对你有用:

import java.util.concurrent.*;
import static net.mindview.util.Print.*;
class Meal {
private final int orderNum;
public Meal(int orderNum) { this.orderNum = orderNum; }
public String toString() { return "Meal " + orderNum; }
}
class WaitPerson implements Runnable {
private Restaurant restaurant;
public WaitPerson(Restaurant r) { restaurant = r; }
public void run() {
try {
while(!Thread.interrupted()) {
synchronized(this) {
while(restaurant.meal == null)
wait(); // ... for the chef to produce a meal
}
print("Waitperson got " + restaurant.meal);
synchronized(restaurant.chef) {
restaurant.meal = null;
restaurant.chef.notifyAll(); // Ready for another
}
}
} catch(InterruptedException e) {
print("WaitPerson interrupted");
}
}
}
class Chef implements Runnable {
private Restaurant restaurant;
private int count = 0;
public Chef(Restaurant r) { restaurant = r; }
public void run() {
try {
while(!Thread.interrupted()) {
synchronized(this) {
while(restaurant.meal != null)
wait(); // ... for the meal to be taken
}
if(++count == 10) {
print("Out of food, closing");
restaurant.exec.shutdownNow();
}
printnb("Order up! ");
synchronized(restaurant.waitPerson) {
restaurant.meal = new Meal(count);
restaurant.waitPerson.notifyAll();
}
TimeUnit.MILLISECONDS.sleep(100);
}
} catch(InterruptedException e) {
print("Chef interrupted");
}
}
}
public class Restaurant {
Meal meal;
ExecutorService exec = Executors.newCachedThreadPool();
WaitPerson waitPerson = new WaitPerson(this);
Chef chef = new Chef(this);
public Restaurant() {
exec.execute(chef);
exec.execute(waitPerson);
}
public static void main(String[] args) {
new Restaurant();
}
}
moon197896 2009-07-29
  • 打赏
  • 举报
回复
呵呵,我知道20分少了点,不过念在在下论坛新人的份儿上,请大家不吝赐教阿。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧