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

Java-具有wait()和notify()的两个线程,java,multithreading,java-threads,Java,Multithreading,Java Threads,我是Java编程新手。我想使用wait()和notify()运行两个线程。但是我不能将任务标志用于线程同步、睡眠、屈服或等待(参数)。有人能帮我把它改成不睡觉吗。 这是我的主课 public class mainClass{ public static void main(String args[]) throws InterruptedException { final Processor processor = new Processor();

我是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.");
       }          
    }
这是我的输出

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次

也许你需要这样做

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);
    }
}
}
  • 生产者应该一起创建100个任务(一次一个),并在每个任务完成后等待消费者完成
  • 使用者应等待任务,并在完成当前任务时通知生产者,然后等待下一个任务
  • 所以您的main类应该是这样的,循环应该在producer()和consumer()方法中

    处理器可能是这样的

    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);
        }
    }
    }
    
    公共类处理器{
    private int taskNo=0;//当前任务的编号
    //(0=没有任务,但将有)
    //(-1=不会有更多任务)
    public void product()引发InterruptedException{
    已同步(此){
    对于(int i=0;i<100;i++){
    taskNo=i+1;//制作任务编号(i+1)
    System.out.println(“培训师制作”+taskNo+“任务…”);
    notify();//通知使用者任务已完成
    wait();//然后等待消费者完成…zzzz。。。
    System.out.println(“”);
    }
    taskNo=-1;//将不再有任务
    notify();//将此事通知消费者
    }
    }
    public void consume()引发InterruptedException{
    已同步(此){
    做{
    如果(taskNo==0){
    wait();//没有任务要做,正在等待…zzzz。。。
    }
    如果(任务编号!=-1){
    System.out.println(“运动人正在做”+taskNo+“任务…”);
    taskNo=0;//将任务设置为完成
    notify();//通知生产者任务已完成
    }
    }而(taskNo!=-1);
    }
    }
    }
    
    通常有一个队列而不是taskNo变量,生产者在队列中放置任务,消费者从队列中获取任务。但在您的情况下,队列一次只能有一个任务,因为生产者应该等待消费者完成。因此,您可以使用简单变量(taskNo)代替队列。

    提示:

  • 正确使用
    wait
    需要等待特定的事情发生。正确的实现是这样的

    synchronize (x) {
        while (!x.itHasHappened()) {
             x.wait();  // for it to happen
        }
    }
    
    循环是必要的,因为可能会在基本锁上获得虚假通知

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


  • 如果您在没有线程等待的情况下进行通知,它将丢失。在进行状态更改后,您需要通知,然后需要在wait()上的循环中检查该状态更改,因为它可能会错误地唤醒。此处记录了
    wait()
    notify()
    的正确用法。您希望/期望输出是什么样的?因为您的
    synchronized
    块根本不保护任何状态,所以没有什么要通知的,也没有什么要等待的。唯一需要等待的是某种状态的改变,这需要有某种状态需要改变。唯一需要通知的是状态的一些变化,没有状态变化,就没有什么需要通知的。在使用
    notify
    wait
    之前,必须先设置一些状态,其中一个线程可能要等待该状态的更改,而另一个线程可能需要通知该状态的更改。
    synchronize (x) {
        while (!x.itHasHappened()) {
             x.wait();  // for it to happen
        }
    }