2017-03-14 44 views
0

我是Java编程新手。我想用wait()和notify()来运行两个线程。但我不能使用线程同步,睡眠,良率或等待(参数)任务标志。我写了它,但我不得不使用睡眠。有人可以帮助我改变它没有睡眠。 这是我的主类Java - 两个线程wait()和notify()

public class mainClass{ 

     public static void main(String args[]) throws InterruptedException { 

      final Processor processor = new Processor(); 

      for(int i=0; i<100; i++){ 

       final int z = i; 
       Thread trainer = new Thread(new Runnable(){ 

        public void run(){ 
         try{ 
          processor.produce(z); 
         }catch(InterruptedException e){ 
          e.printStackTrace(); 
         } 
        }   
       }); 

       Thread sportsman = new Thread(new Runnable(){ 

        public void run(){ 
         try{ 
          processor.consume(z); 
         }catch(InterruptedException e){ 
          e.printStackTrace(); 
         } 
        }   
       }); 

       trainer.start(); 
       sportsman.start(); 

       trainer.join(); 
       sportsman.join(); 

      } 
      System.out.println("100 Tasks are Finished."); 
     }   
    } 

这是我的第二个类。

public class Processor { 

public void produce(int n) throws InterruptedException { 
    synchronized (this){ 
     System.out.println("Trainer making " + (n+1) + " Task..."); 
     wait(); 
     System.out.println(""); 
    } 
} 

public void consume(int m) throws InterruptedException { 
    Thread.sleep(1); 
    //I want to run the code without using sleep and get same output 
    synchronized (this){ 
     System.out.println("Sportman doing " + (m+1) + " Task..."); 
     notify(); 
    } 
} 
} 

这是我的输出。

Trainer making 1 Task... 
Sportman doing 1 Task... 

Trainer making 2 Task... 
Sportman doing 2 Task... 

. 
. 
. 

Trainer making 99 Task... 
Sportman doing 99 Task... 

Trainer making 100 Task... 
Sportman doing 100 Task... 

100 Tasks are Finished. 

谢谢。我的英语不好。对不起。

+0

如果您没有等待的线程通知它会丢失。在进行状态更改后需要通知,那么您需要在wait()的循环中检查状态更改,因为它可能会虚假地唤醒。 –

+0

这里记录了正确使用'wait()'和'notify()'。 https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html –

+0

你想要/期望输出看起来像什么? –

回答

0

在mainClass中创建了100次两个线程,我认为你应该只创建两个线程,并在这两个线程中循环运行100次。

也许你需要做这样的事情...

  1. 生产企业应共同创造100任务(一次一个),并待兴,为消费者每个任务后。
  2. 消费者应该等待任务,并在完成当前任务时通知生产者,他们等待下一个任务。

所以你的mainClass应该看起来像这样,循环应该在producer()和consumer()方法中。

public class mainClass { 

public static void main(String args[]) throws InterruptedException { 

    final Processor processor = new Processor(); 

    Thread trainer = new Thread(new Runnable() { 
     public void run() { 
      try { 
       processor.produce(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    Thread sportsman = new Thread(new Runnable() { 
     public void run() { 
      try { 
       processor.consume(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

    trainer.start(); 
    sportsman.start(); 

    trainer.join(); 
    sportsman.join(); 

    System.out.println("100 Tasks are Finished."); 
} 

} 

和处理器也许这样的事情...

public class Processor { 

private int taskNo = 0; // the number of the current task 
         // (0 = there is no task, but will be) 
         // (-1 = there won't be more task) 

public void produce() throws InterruptedException { 
    synchronized (this) { 
     for (int i = 0; i < 100; i++) { 
      taskNo = i + 1; // making a task number (i+1) 
      System.out.println("Trainer making " + taskNo + " Task..."); 
      notify(); // notifies the consumer that the task was made 
      wait(); // and waiting the consumer to finish... zzzz... 
      System.out.println(""); 
     } 
     taskNo = -1; // there will be no more task 
     notify(); // notify the consumer about it 
    } 
} 

public void consume() throws InterruptedException { 
    synchronized (this) { 
     do { 
      if (taskNo == 0) { 
       wait(); // there is no task to do, waiting... zzzz... 
      } 
      if (taskNo != -1) { 
       System.out.println("Sportman doing " + taskNo + " Task..."); 
       taskNo = 0; // sets the task to done 
       notify(); // notifies the producer that the task was done 
      } 
     } while (taskNo != -1); 
    } 
} 
} 

通常有一个队列,而不是taskNo变量,其中生产者把任务和消费者在需要的任务。但在你的情况一次只能有一个任务,因为生产者应该等待消费者完成。所以你可以使用一个简单的变量(taskNo)而不是一个队列。

1

提示:

  1. 的正确使用wait涉及等待具体的事情发生。正确执行是这样的

    synchronize (x) { 
        while (!x.itHasHappened()) { 
         x.wait(); // for it to happen 
        } 
    } 
    

    环路是必要的,因为它可以得到一个基本锁定虚假通知。

  2. 在您的具体示例中,问问自己什么必须等待发生什么。我认为你错了。 produce(N)究竟等什么,为什么?

相关问题