簡體   English   中英

Java-兩個具有wait()和notify()的線程

[英]Java - two threads with wait() and 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.

謝謝。 我的英語不好。 對不起

提示:

  1. wait的正確用法包括等待特定的事件發生。 正確的實現是這樣的

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

    循環是必需的,因為有可能在原始鎖上收到虛假通知。

  2. 在您的特定示例中,問自己必須等待什么發生。 我想你錯了。 什么是produce(N)實際等待,為什么?

在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)代替隊列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM