你的
MyProducer.run();
MyCustomer.run();
应该改为.start();
我想这个不用解释了吧?

解决方案 »

  1.   

    MyProducer.start();
    MyCustomer.start();start才是启动线程的方法,start的内部会自动去开始执行run方法的
      

  2.   

    start()确实是开始线程执行的一种方法,但SUN并不建议是它,而是使用run(),因为run()方法不是直接开始线程的执行,而是将线程放入等待队列中。小弟估计的错误应该是出在while()循环中,还有就是notify()方法没有唤起休眠线程
    大家再帮我看看吧....
      

  3.   

    demon_duke() 可不可以再详细一点??
      

  4.   

    你这个是wait()的问题
    wait是在一个对象上等待
    需要这个对象调用notify()去唤醒
    你好好看看wait和notify吧
    我把你的代码改了
    现在好使了
    public synchronized void add(){
    Course2.productionNumber++;
    System.out.println("produce = " + productionNumber);
    try{
    // notify();
    this.notifyAll();
    }
    catch(Exception e){

    }
    if(productionNumber >= 10){
    try{
    this.wait();
    }
    catch(Exception e){

    }
    }

    }
    public synchronized void minus(){
    System.out.println("i'm the customer");
    if(productionNumber > 0){
    productionNumber--;
    System.out.println("consume = " + productionNumber);
    }
    else{
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    } }

    }
    public synchronized void produce(){
     add();
    }
    public synchronized void consume(){
    minus();
    }
      

  5.   

    谢谢,我吃了饭回来会试一试的。可不可以再讲一讲notify()和notifyAll()的区别呢??
      

  6.   

    这个的区别不大
    我是在还没确定错误时试着看的
    notify()是唤起一个线程
    我用notifyAll()来唤起所有线程
    在你这里在一个时刻只有一个线程在等待
      

  7.   

    to  demon_duke()师兄我已经试过了,但好像不能运行,大概是因为synchronized的原因吧...to ChDw(米) 师兄不好意思是我记错了,sun部建议使用的是run和join方法,而start方法是运行线程的标准方法,我已经盖过了,但问题依旧,请各位高手再帮我看看吧....
      

  8.   

    是wait()和notify()的问题,他们能够相互通知是因为用了相同的锁。
    本题中wait()实际上是this.wait(),他用的锁是各自的类实例,即MyProducer,MyCustomer,两个地方用的锁不一样,从而导致notify()无法通知wait()。可做如下改动:
    在course2类下:private Object valueLock = new Object();每次调用wait()或notify()时如下处理:synchronized ( valueLock ) {
              try {
                valueLock.notify();//或wait()
              }
      

  9.   

    to yinwenjie(java入门中) 你完全错误!!
    线程【必须】使用start方法启动,Sun只是不建议使用stop方法来停止线程线程的start方法你不应该去覆盖,你的代码只是应该覆盖run方法,你调用thread.start的时候
    JVM会启动一个线程来开始执行run方法直到它退出为止
      

  10.   

    to ChDw(米) :哈哈哈,使我字打错了,应该是“我改过了”,我手误打成了“我盖过了”。多谢老兄了,我初学者,还希望大家多多指点啊!
      

  11.   

    to cs_tar() :谢谢,但如果我在producer中定义了一个新的customer类对象,那么在Course2类中就存在了两个customer对象了,而wait(),notify()方法不是静态方法,也就是说这两个对象的阻塞、就绪状态相互独立。我想错误还是应该在while循环中,我看书上说的while循环在线程中非常自私,不知道是不是这样?
      

  12.   

    我已用我上述方法调试通过。如果你要定义两个customer对象,只要把valueLock.notify()改成valueLock.notifyAll(),再把consumn方法里的这一段:else{
    try{
    wait();
    }
    catch(Exception w){
    System.out.println("Exception!!");
    }
    }
    改成while(productionNumber<=0){
                                      synchronized(valuelock)
                                     {
    try{
    valuelock.wait();
    }
    catch(Exception w){
    System.out.println("Exception!!");
    }
    }就可以了。
      

  13.   

    其实这里的问题就是对象锁的问题
    锁是加在对象上的
    一个线程运行需要取得一个对象的锁
    楼主开始时的锁是加的两个对象producer和custmer上了
    producer通知等待producer的锁的进程,不会去通知等待custmer的进程
    custmer通知等待custmer的锁的进程,它也不会去通知等待producer的进程
    而那个producer、custmer线程等待的是它自己的锁
    他们谁也不会去通知其他人
    我改过以后的是把锁加在了那个course2上的
    完整代码如下:
    public class Course2 {

    private static int productionNumber = 1;//用于记录已生产的但还未消费的产品个数

    /**
     * 生产者类,用线程方式不停的生产产品,
     * */
    public synchronized void add(){
    Course2.productionNumber++;
    System.out.println("i'm the produce");
    System.out.println("produce = " + productionNumber);
    try{
    // notify();
    this.notifyAll();
    }
    catch(Exception e){

    }
    if(productionNumber >= 10){
    try{
    this.wait();
    }
    catch(Exception e){

    }
    }

    }
    public synchronized void minus(){
    System.out.println("i'm the customer");
    if(productionNumber > 0){
    productionNumber--;
    System.out.println("consume = " + productionNumber);
    this.notify();
    }
    else{
    try {
    this.wait();
    } catch (InterruptedException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    } }

    }
    public class producer extends Thread{
    /**
     * 构建起用于初始化一些属性
     * */
    public producer(){

    }
    /**
     * 此方法用于生产者不停的生产产品
     * */
    public synchronized void produce(){
     add();
    }

    /**
     * 覆盖run方法
     * */
    public void run(){
    while(true){
    this.produce();

    try {
    sleep(700);
    } catch (InterruptedException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    }

    }
    }
    }

    /**
     * 消费者类,用于在productionNumber != 0的情况下消费产品
     * */
    public class customer extends Thread{
    /**
     * 构建器用于处理一些属性
     * */
    public customer(){

    }

    /**
     * 此方法用于消费者消费产品
     * */
    public synchronized void consume(){
    minus();
    }

    /**
     * 覆盖run方法
     * */
    public void run(){
    while(true){
    this.consume();
    try {
    sleep(900);
    } catch (InterruptedException e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    }
    }

    }
    }

    public static void main(String[] src){
    Course2 MyCourse2 = new Course2();
    Course2.producer MyProducer = MyCourse2.new producer();//生产者对象
    Course2.customer MyCustomer = MyCourse2.new customer();//消费者对象

    MyProducer.setPriority(Thread.MAX_PRIORITY);
    MyCustomer.setPriority(Thread.MIN_PRIORITY);
    MyProducer.start();
    MyCustomer.start();
    }
    }