Java - 带有wait()和notify()的两个线程

时间:2017-03-14 20:18:38

标签: java multithreading java-threads

我是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.
谢谢你。我的英语不好。对不起。

2 个答案:

答案 0 :(得分:1)

提示:

  1. 正确使用wait涉及等待特定事件发生。正确的实现是这样的

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

    循环是必要的,因为可以在原始锁上获得虚假通知。

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

答案 1 :(得分:0)

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

可能你需要做这样的事情......

  1. 制作人应该共同创建100个任务(一次一个)并在每个任务之后等待消费者完成。
  2. 消费者应该等待任务并在完成当前任务时通知生产者,他们等待下一个任务。
  3. 所以你的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变量,生产者放置任务,消费者从中获取任务。但在你的情况下,队列一次只能有1个任务,因为生产者应该等待消费者完成。因此,您可以使用简单变量(taskNo)而不是队列。