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
”这种情况是不是意味着生产和消费进程未能被独占锁定。有什么方法可以解决呢?

解决方案 »

  1.   

    给你贴一个生产-消费者的例子,是《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();
    }