下面是代码示例:使用5或6个值后,线程被挂起
我不知道我在哪里丢失任何东西。还有一个疑问,我是关于调用MyIncrementor类的构造函数的。最初,我试图通过创建MyIncrementor类的新对象来调用Producer和Consumer类中的get和set,但它也无法正常工作

/**
 *
 */
package multithreadingDemo;

/**
 * @author Aquib
 *
 */
public class ThreadCommDemo {

    /**
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        MyIncrementor mi=new MyIncrementor();
        Producer1 p=new Producer1(mi);
        Consumerrs c=new Consumerrs(mi);
        Thread t1=new Thread(p);
        Thread t2=new Thread(c);
        t1.start();
        t2.start();


    }

}



class MyIncrementor {
    int myCount;
    boolean valueSet;

    /**
     * @return the myCount
     */
    public synchronized int getMyCount() {
        if (!valueSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println("get" + myCount);
        valueSet = true;
        notifyAll();
        return myCount;
    }

    /**
     * @param myCount
     *            the myCount to set
     */
    public synchronized void setMyCount(int myCount) {
        if (valueSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println("Set" + myCount);
        this.myCount = myCount;
        valueSet = false;
        notifyAll();
    }

}

class Producer1 implements Runnable {
    MyIncrementor mi;

    public Producer1(MyIncrementor mi) {
        // TODO Auto-generated constructor stub
        this.mi=mi;
    }

    public void run() {

        for (int i = 1; i < 10; i++) {
            mi.setMyCount(i);
            System.out.println("Produced" + mi.myCount);
             try
             {
                   Thread.currentThread().sleep((int)(Math.random() * 100));
             }
             catch (InterruptedException ie)
             {
                   ie.printStackTrace();
             }
        }
    }
}

class Consumerrs implements Runnable {
    MyIncrementor mi;

    public Consumerrs(MyIncrementor mi) {
        // TODO Auto-generated constructor stub
        this.mi=mi;
    }

    public void run() {

        for (int i = 1; i < 10; i++) {
            int val = mi.getMyCount();
            System.out.println("Consumed" + val);
        }

    }

}

最佳答案

您在MyIncrementor类中只是逻辑上的错误,您在设置valueSet时设置不正确,因此您必须更改条件或在getMyCountsetMyCount方法中设置反之亦然。

因此,这是MyIncrementor的更正版本:

class MyIncrementor {
  int myCount;
  boolean valueSet = false; //line changed - just to show that by default it is initialized to false

  /**
   * @return the myCount
   */
  public synchronized int getMyCount() {
    while (!valueSet) { //corrected as advised in comments, see @Tom Hawtin - tackline answer for details
      try {
        wait();
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    System.out.println("get" + myCount);
    valueSet = false; //line changed - after getting the value set flag to false
    notifyAll();
    return myCount;
  }

  /**
   * @param myCount
   *            the myCount to set
   */
  public synchronized void setMyCount(int myCount) {
    while (valueSet) { //corrected as advised in comments, see @Tom Hawtin - tackline answer for details
      try {
        wait();
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    System.out.println("Set" + myCount);
    this.myCount = myCount;
    valueSet = true; //line changed - after setting the value set flag to true
    notifyAll();
  }

}

10-08 13:34