这是孙卫琴《Java面向对象编程》中的关于线程同步的生产者-消费者问题的示例。但运行一下就卡死不动了。我猜可能是发生了死锁。但怎么都看不出问题在哪。肯请高手指点迷津!!!!!!!public class SyncTest {
public static void main(String[] args ) {
Stack stack1 = new Stack("stack1");
Producer producer1 = new Producer( stack1, "producer1");
Consumer consumer1 = new Consumer(stack1, "consumer1");
Consumer consumer2 = new Consumer(stack1, "cosumer2"); Stack stack2 = new Stack("stack2");
Producer producer2 = new Producer(stack2, "producer2");
Producer producer3 = new Producer(stack2, "producer3");
Consumer consumer3 = new Consumer(stack2, "consumer3");
}
}/** 生产者线程*/
class Producer extends Thread {
private Stack theStack;
public Producer ( Stack s, String name ) {
super(name);
theStack = s;
start(); //启动自身生产者线程
}
public void run() {
String goods;
for (int i = 0 ; i < 150; i++ ) {
goods = "goods" +(theStack.getPoint() + 1);
theStack.push(goods); System.out.println(getName() + " : push " + goods + "to " + theStack.getName() ); yield();
}
}
}/** 消费者线程*/
class Consumer extends Thread { //遇到数组越界没有捕捉机制,会终止当前运行的线程
private Stack theStack;
public Consumer ( Stack s, String name ) {
super(name);
theStack = s;
start();
} public void run() {
String goods;
for (int i = 0; i < 150; i++ ) {
goods = theStack.pop();
System.out.println(getName() + " : pop " + goods + " from " + theStack.getName() ); yield();
}
}
}/** 堆栈*/
class Stack {
private String name;
private String[] buffer = new String[100];
int point = -1; public Stack(String name) { this.name = name; }
public String getName () { return name; } public synchronized int getPoint() { return point; } public synchronized String pop() {
this.notifyAll();
while(point == -1) {
System.out.println(Thread.currentThread().getName() + " : wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
String goods = buffer[point];
buffer[point] = null;
Thread.yield();
point -- ;
return goods;
} public synchronized void push(String goods) {
this.notifyAll(); while(point == buffer.length - 1) {
System.out.println(Thread.currentThread().getName() + ": wait");
try {
this.wait();
}catch(InterruptedException e) { throw new RuntimeException(e); }
}
point++;
Thread.yield();
buffer[point] = goods;
}
}

解决方案 »

  1.   

    你这个是多个生产者与多个消费者之间的问题,发一个我在别的帖子上回的吧,代码修改过了。意思差不多class Consumer extends Thread {   
        
        private String consumerName = null;   
           
        private StoreHouse storeHouse = null;   
      
        public Consumer(String consumerName, StoreHouse storeHouse) {   
            this.consumerName = consumerName;   
            this.storeHouse = storeHouse;   
        }   
           
        public void setConsumerName(String consumerName) {   
            this.consumerName = consumerName;   
        }   
           
        public String getConsumerName() {   
            return consumerName;   
        }   
           
        public synchronized void consumerProduct() {   
            while (true) {   
                Product p = storeHouse.pop();
                //System.out.println(getConsumerName() + " 消费了 " + p);   
                storeHouse.print();
                try {   
                    Thread.sleep(3000);   
                } catch (InterruptedException e) {   
                    return;   
                } 
            }   
        }   
      
        public void run() {   
            consumerProduct();   
        }   
    } class Producer extends Thread {   
        
        private static int i = 0;
        private String producerName = null;   
      
        private StoreHouse storeHouse = null;   
      
        public Producer(String producerName, StoreHouse storeHouse) {   
            this.producerName = producerName;   
            this.storeHouse = storeHouse;   
        }   
      
        public void setProducerName(String producerName) {   
            this.producerName = producerName;   
        }   
      
        public String getProducerName() {   
            return producerName;   
        }   
           
        public synchronized void produceProduct() {
            while (true) {   
                i++;   
                Product pro = new Product(i);   
                storeHouse.push(pro);   
                //System.out.println(getProducerName() + " 生产了 " + pro);   
                storeHouse.print();
                try {   
                    Thread.sleep(1000);   
                } catch (InterruptedException e) {   
                    e.printStackTrace();
                    return;   
                }
            }   
        }   
      
        public void run() {   
            produceProduct();   
        }   
      
    }   class Product {   
          
        private int productId = 0;   
           
        public Product(int productId) {   
            this.productId = productId;   
        }   
      
        public synchronized int getProductId() {   
            return productId;   
        }   
      
        public String toString() {   
            return Integer.toString(productId);   
        }   
    }  class StoreHouse {   
        private int pushPoint = 0;   
        private int popPoint = 0; 
        private int size = 0; 
        
        private final int fifoSize = 2;
        private Product[] products = new Product[10];   
      
        public synchronized void push(Product product) {   
            while (size == fifoSize) { 
                try {   
                    System.out.println("仓库已满,正等待消费...");   
                    wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            System.out.println("可以生产");
            products[pushPoint] = product;   
            System.out.println("生产了" +  product);
            pushPoint = (pushPoint + 1) % fifoSize;
            size++;
            System.out.print("########");
            print();
            this.notifyAll();
        }   
      
        public synchronized Product pop() {   
            Product pro = null;   
            while (size == 0) {
                try {   
                    System.out.println("仓库已空,正等待生产...");   
                    wait();   
                } catch (InterruptedException e) {   
                    System.out.println("stop push product because other reasons");   
                }   
            }   
            System.out.println("可以消费");
            pro = products[popPoint];   
            System.out.println("消费了"+ pro);
            popPoint = (popPoint + 1) % fifoSize;
            size--;
            System.out.print("&&&&&&&&&&");
            print();
            this.notifyAll();
            return pro;   
        }   
        
        public synchronized void print(){
            System.out.println("pPonit = " + this.pushPoint + ", cPoint =" + this.popPoint + ", size is " + this.size);
        }
    }public class Test {       StoreHouse storeHouse = new StoreHouse();   
        Producer producer1 = new Producer("生产者1", storeHouse);   
        Producer producer2 = new Producer("生产者2", storeHouse);   
        Producer producer3 = new Producer("生产者3", storeHouse);  
        
        Consumer comsumer1 = new Consumer("消费者1", storeHouse);
        Consumer comsumer2 = new Consumer("消费者2", storeHouse);
        public Test(){
            producer1.start();
            comsumer1.start();
            producer2.start();
            producer3.start();
            comsumer2.start();
        }
        public static void main(String[] args) {  
            new Test();
        }
    }
      

  2.   

    死锁不会死机吧,只是不输出死循环那才叫卡死,点STOP都不鸟你……
      

  3.   

    你的wait()方法后面没有notify()
    线程停在那里等待  有了资源当然要唤醒才能继续
      

  4.   

    问题已解决,里面有详细解释,各位高手是否同意这个说法?我Java没学多久,渴望高手指点。代码改动如下:
    public class SyncTest2 {
    public static void main(String[] args ) {
    Stack stack1 = new Stack("stack1");
    Producer producer1 = new Producer( stack1, "producer1");
    Consumer consumer1 = new Consumer(stack1, "consumer1");
    Consumer consumer2 = new Consumer(stack1, "cosumer2"); //Stack stack2 = new Stack("stack2");
    //Producer producer2 = new Producer(stack2, "producer2");
    //Producer producer3 = new Producer(stack2, "producer3");
    //Consumer consumer3 = new Consumer(stack2, "consumer3");
    }
    }/** 生产者线程*/
    class Producer extends Thread {
    private Stack theStack;
    public Producer ( Stack s, String name ) {
    super(name);
    theStack = s;
    start(); //启动自身生产者线程
    }
    public void run() {
    String goods;
    for ( int i = 0 ;i < 200 ; i++ ) {
    goods = "goods" +(theStack.getPoint() + 1);
    theStack.push(goods); System.out.println(getName() + " : push " + goods + "to " + theStack.getName() );
    yield();
    }
    }
    }/** 消费者线程*/
    class Consumer extends Thread { //遇到数组越界没有捕捉机制,会终止当前运行的线程
    private Stack theStack;
    public Consumer ( Stack s, String name ) {
    super(name);
    theStack = s;
    start();
    } public void run() {
    String goods;
    for ( int i = 0 ;i < 200 ; i++ ) {
    goods = theStack.pop();
    System.out.println(getName() + " : pop " + goods + " from " + theStack.getName() );
    yield();
    }
    }
    }/** 堆栈*/
    class Stack {
    private String name;
    private String[] buffer = new String[100];
    int point = -1; public Stack(String name) { this.name = name; }
    public String getName () { return name; } public synchronized int getPoint() { return point; } public synchronized String pop() {
    this.notifyAll();
    while(point == -1) {
    System.out.println(Thread.currentThread().getName() + " : wait");
    //this.notifyAll(); //若把notifyAll()移到这里,就能一直地执行下去了……
    try { //生产者执行了200次后撤销,正好这一刻,剩下两个消费者,其中一个消费者(假设是consumer1)获得对象锁,并通知另一个消费者,使其在对象锁上等待。
    //consumer1执行wait()进入对象池中并释放对象锁。然后consumer2获得对象锁,并通知consuer1,使其在对象锁上等待。
    //然后consumer2执行wait()进入对象池中并释放对象锁。接着consumer1又获得对象锁,但这次是在while循环体内,没有机会执行notifyAll(),这次没有线程能唤醒他了。
    this.wait(); //而此刻consumer2也在对象池中。所以两个线程都在对象池中,没办法唤醒,程序就这样停在这里了。
    //System.out.println("I'm after this.wait()");
    }catch(InterruptedException e) { throw new RuntimeException(e); }
    }
    String goods = buffer[point];
    buffer[point] = null;
    Thread.yield();
    point -- ; return goods; } public synchronized void push(String goods) {
    this.notifyAll(); while(point == buffer.length - 1) {
    System.out.println(Thread.currentThread().getName() + ": wait");
    //this.notifyAll();
    try {
    //Thread.sleep(50);
    this.wait();
    }catch(InterruptedException e) { throw new RuntimeException(e); }
    }
    point++;
    Thread.yield();
    buffer[point] = goods;
    }
    }