Как заставить notify () выполнить перед wait (), я пытался использовать sleep (), но все еще не работает - PullRequest
0 голосов
/ 22 января 2020

У меня есть следующий пример потока:

class Q
{
    int num;
    public synchronized void put(int num) {
        System.out.println("Put :"+num);
        this.num = num;
        try {Thread.sleep(100);} catch (Exception e) {}
        notify();
        try {wait();} catch (Exception e) {}
    }
    public synchronized void get() {
        try {wait();} catch (Exception e) {}
        System.out.println("Get :"+num);
        notify();
    }
}
class Producer implements Runnable
{
    Q q;
    public Producer(Q q) {
        this.q = q;
        Thread t = new Thread(this,"Producer");
        t.start();
    }
     public void run() {
         int i = 0;
         while(true) {
             q.put(i++);
                try {Thread.sleep(1000);} catch (Exception e) {}
         }  
     }
}
class Consumer implements Runnable
{
    Q q;
    Thread t;
    public Consumer(Q q) {
        this.q = q;
        t = new Thread(this,"Consumer");
        t.start();
    }
     public void run() {
         while(true) {
             q.get();
            try {Thread.sleep(500);} catch (Exception e) {}
         }     
     }
}
public class InterThread {
    public static void main(String[] args) {
        Q q = new Q();
        new Producer(q);
        new Consumer(q);
    }
}

Я пытаюсь запустить два потока, потребителя и производителя, в al oop. разделяя один и тот же объект q, один поток увеличивает значение q.num и печатает его значение, а другой потребляет q.num, просто печатая его значение. Результат, который я получаю в консоли: «Put: 0» и останавливается там, потребительский поток не вызывается, хотя я использовал Thread.sleep(100); перед вызовом notify () в потоке производителя, почему !!?

1 Ответ

1 голос
/ 22 января 2020

В этом случае поток источника запускается перед потребителем. notify () вызывается, после чего вызывается wait (). Поток производителя переходит в состояние ожидания, снимает полученную блокировку.

// producer
notify();
try {
   System.out.println(Thread.currentThread().getName() + " Put :"+num);
   this.wait(); // lock released
} 
catch (Exception e) {

}

Теперь поток потребителя получает блокировку, выполняется wait (). Consumer переходит в состояние ожидания.

// consumer
try {
   System.out.println(Thread.currentThread().getName() + "Get :"+num);
   this.wait(); // Both the threads are waiting
} 
catch (Exception e) { 

}

Теперь оба потока ожидают notify вызова из другого потока. Обратите внимание, что метод Sleep() не снимает блокировку, поэтому нет точка в вызове Thread.sleep до уведомления производителя

разница между ожиданием и сном

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...