JAVA多线程生产者与消费者问题昨天看了一下资料,模仿着写了个,怎么跑起来死锁了?望各位大牛看看哪代码有误 ?
正确的情况 应该是 ,打印 生产 一个 ,接着打印 消费一个 (假设最多只能存放一个产品)/**
 * 店员类
 * 假设 店内只有一个产品架 只能存放一个产品
 * 
 *
 */
public class Clerk { //-1代表店内没有可用产品
private int product = -1;

//生产一个产品
public synchronized void setProduct(int product) throws InterruptedException{

if(this.product != -1){
//产品架上还有产品 等待消费者消费
wait();
}
this.product = product;
System.out.println("当前线程"+Thread.currentThread().getName()+"生产第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}

//消费一个产品
public synchronized void getProduct(int product) {

if(this.product == -1){
//没有产品 等待生产者生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

this.product = -1;
System.out.println("当前线程"+Thread.currentThread().getName()+"消费第"+product+"个产品");
//解锁 并通知其他线程进入线程等待队列排队
notify();
}
}/**
 * 生产者
 *
 *
 */
public class Produce implements Runnable { private Clerk clerk;

public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始生产");
try {
clerk.setProduct(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}/**
 * 消费者
 * 
 *
 */
public class Consume implements Runnable { private Clerk clerk;

public void run(){
for(int i=1; i<=10; i++){
if(this.clerk == null){
clerk = new Clerk();
}
System.out.println("----当前线程"+Thread.currentThread().getName()+ "开始消费");
try {
clerk.getProduct(i);
} catch (Exception e) {
e.printStackTrace();
};
}
}
}//调用类
public class Main { public static void main(String[] args){

Produce pro = new Produce();
Thread produceThread = new Thread(pro);
produceThread.start();

Consume con = new Consume();
Thread consumeThread = new Thread(con);
consumeThread.start();

}
}

解决方案 »

  1.   

    一下是上学堂的代码,建议楼主看看
    public class ProducerConsumer {
    public static void main(String[] args) {
    SyncStack ss = new SyncStack();
    Producer p = new Producer(ss);
    Consumer c = new Consumer(ss);
    new Thread(p).start();
    new Thread(p).start();
    new Thread(p).start();
    new Thread(c).start();
    }
    }class WoTou {
    int id; 
    WoTou(int id) {
    this.id = id;
    }
    public String toString() {
    return "WoTou : " + id;
    }
    }class SyncStack {
    int index = 0;
    WoTou[] arrWT = new WoTou[6];

    public synchronized void push(WoTou wt) {
    while(index == arrWT.length) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.notifyAll();
    arrWT[index] = wt;
    index ++;
    }

    public synchronized WoTou pop() {
    while(index == 0) {
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.notifyAll();
    index--;
    return arrWT[index];
    }
    }class Producer implements Runnable {
    SyncStack ss = null;
    Producer(SyncStack ss) {
    this.ss = ss;
    }

    public void run() {
    for(int i=0; i<20; i++) {
    WoTou wt = new WoTou(i);
    ss.push(wt);
    System.out.println("生产了:" + wt);
    try {
    Thread.sleep((int)(Math.random() * 200));
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }class Consumer implements Runnable {
    SyncStack ss = null;
    Consumer(SyncStack ss) {
    this.ss = ss;
    }

    public void run() {
    for(int i=0; i<20; i++) {
    WoTou wt = ss.pop();
    System.out.println("消费了: " + wt);
    try {
    Thread.sleep((int)(Math.random() * 1000));
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }
      

  2.   


    //调用类
    public class Main { public static void main(String[] args) {

    //生产者和消费者公用一个clerk,通过构造函数分别给其传值
    Clerk clerk = new Clerk();

    Produce pro = new Produce(clerk);
    Thread produceThread = new Thread(pro);
    produceThread.start(); Consume con = new Consume(clerk);
    Thread consumeThread = new Thread(con);
    consumeThread.start(); }
    }/**
     * 消费者
     * 
     * 
     */
    public class Consume implements Runnable { private Clerk clerk;

    public Consume(Clerk clerk) {
    this.clerk = clerk;
    } public void run() {
    for (int i = 1; i <= 10; i++) {
    if (this.clerk == null) {
    clerk = new Clerk();
    }
    System.out.println("----当前线程" + Thread.currentThread().getName()
    + "开始消费");
    try {
    clerk.getProduct(i);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    }/**
     * 生产者
     * 
     * 
     */
    public class Produce implements Runnable { private Clerk clerk;

    public Produce(Clerk clerk) {
    this.clerk = clerk;
    } public void run() {
    for (int i = 1; i <= 10; i++) {
    if (this.clerk == null) {
    clerk = new Clerk();
    }
    System.out.println("----当前线程" + Thread.currentThread().getName()
    + "开始生产");
    try {
    clerk.setProduct(i);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }/**
     * 店员类 假设 店内只有一个产品架 只能存放一个产品
     * 
     * 
     */
    public class Clerk { // -1代表店内没有可用产品
    private int product = -1; // 生产一个产品
    public synchronized void setProduct(int product)
    throws InterruptedException { if (this.product != -1) {
    // 产品架上还有产品 等待消费者消费
    wait();
    }
    this.product = product;
    System.out.println("当前线程" + Thread.currentThread().getName() + "生产第"
    + product + "个产品");
    // 解锁 并通知其他线程进入线程等待队列排队
    notify();
    } // 消费一个产品
    public synchronized void getProduct(int product) { if (this.product == -1) {
    // 没有产品 等待生产者生产
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.product = -1;
    System.out.println("当前线程" + Thread.currentThread().getName() + "消费第"
    + product + "个产品");
    // 解锁 并通知其他线程进入线程等待队列排队
    notify();
    }
    }
      

  3.   

    因为你的2个线程没有共享同一资源,我帮你的代码修改如下直接可以运行 
    注意main方法我修改的部分 以及2个线程对象的构造方法.修改后2个线程共享同一资源
    /**
     * 店员类 假设 店内只有一个产品架 只能存放一个产品
     * 
     * 
     */
    class Clerk { // -1代表店内没有可用产品
    private int product = -1; // 生产一个产品
    public synchronized void setProduct(int product)
    throws InterruptedException { if (this.product != -1) {
    // 产品架上还有产品 等待消费者消费
    wait();
    }
    this.product = product;
    System.out.println("当前线程" + Thread.currentThread().getName() + "生产第"
    + product + "个产品");
    // 解锁 并通知其他线程进入线程等待队列排队
    notify();
    } // 消费一个产品
    public synchronized void getProduct(int product) { if (this.product == -1) {
    // 没有产品 等待生产者生产
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    this.product = -1;
    System.out.println("当前线程" + Thread.currentThread().getName() + "消费第"
    + product + "个产品");
    // 解锁 并通知其他线程进入线程等待队列排队
    notify();
    }
    }/**
     * 生产者
     * 
     * 
     */
    class Produce implements Runnable { private Clerk clerk; public Produce(Clerk c){
    this.clerk = c;
    }
    public void run() {
    for (int i = 1; i <= 10; i++) {
    /*if (this.clerk == null) {
    clerk = new Clerk();
    }*/
    System.out.println("----当前线程" + Thread.currentThread().getName()
    + "开始生产");
    try {
    clerk.setProduct(i);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }/**
     * 消费者
     * 
     * 
     */
    class Consume implements Runnable {
        
    private Clerk clerk;

    public Consume(Clerk c){
    this.clerk= c;
    } public void run() {
    for (int i = 1; i <= 10; i++) {
    /*if (this.clerk == null) {
    clerk = new Clerk();
    }*/
    System.out.println("----当前线程" + Thread.currentThread().getName()
    + "开始消费");
    try {
    clerk.getProduct(i);
    } catch (Exception e) {
    e.printStackTrace();
    }
    ;
    }
    }
    }// 调用类
    public class Main { public static void main(String[] args) {
            Clerk c = new Clerk();
    Produce pro = new Produce(c);
    Thread produceThread = new Thread(pro);
    produceThread.start(); Consume con = new Consume(c);
    Thread consumeThread = new Thread(con);
    consumeThread.start(); }
    }