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

Java - two threads with wait() and notify()

我是 Java 编程新手。我想 运行 两个线程使用 wait() 和 notify()。但是我不能将任务标志用于线程同步、睡眠、屈服或等待(参数)。我写了它,但我不得不使用睡眠。谁能帮我把它改成不睡觉。 这是我的主要class

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.");
       }          
    }

这是我的第二个 class。

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.

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

在 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 变量,生产者在其中放置任务,消费者从中获取任务。但是在您的情况下,队列一次只能有 1 个任务,因为生产者应该等待消费者来完成。所以你可以使用一个简单的变量(taskNo)来代替队列。

提示:

  1. wait 的正确用法包括等待特定的事情发生。正确的实现是这样的

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

    循环是必要的,因为在原始锁上可能会收到虚假通知。

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