/ / powiadom () nie działa w Runnable - java, wielowątkowość

notify () nie działa w Runnable - java, wielowątkowość

Dlaczego nie mogę otrzymać powiadomienia z reader w tym kodzie:

public class ThreadMain {
public Thread reader;
private class SerialReader implements Runnable
{
public void run()
{
try
{
Thread.sleep(3000);

synchronized(this)
{
System.out.println("notifying");
notify();
}
Thread.sleep(3000);
} catch (Exception e){}
}
}

ThreadMain()
{
reader = (new Thread (new SerialReader())   );
}

public static void main(String [] args) {
ThreadMain d= new ThreadMain();
d.reader.start();
synchronized(d)
{
try
{
d.wait();
System.out.println("got notify");
} catch (Exception e) { System.out.println(e); }

}

}
}

Mam tylko linię notifying na wyjściu

Odpowiedzi:

2 dla odpowiedzi № 1

temu notify i wait nie używaj tego samego monitora, więc nie ma szans, aby „rozmawiali” ze sobą.

Jednym prostym rozwiązaniem jest użycie czytnika jako monitora w głównym:

synchronized (d.reader) {
try {
d.reader.wait();
System.out.println("got notify");
} catch (Exception e) {
System.out.println(e);
}
}

0 dla odpowiedzi nr 2

Twój wait() i notify() powinien być pod tym samym monitorem. Obecnie notify W SerialReader pod monitorem this i wait pod monitorem d co jest ThreadMain.

Przy okazji jedna rada notifyAll() zamiast notify()


0 dla odpowiedzi № 3

W twoim Kodzie masz dwa problemy.

Jak sugerują inni. Musisz użyć tej samej blokady, aby korzystać z powiadomienia i czekać. Używasz różnych obiektów do oczekiwania i powiadamiania

Jest jeszcze jeden problem z twoim kodem, nawet jeśliużywasz prawidłowego monitora / blokad. Problem nazywa się Nieodebranymi Powiadomieniami, tzn. Twój wątek SerialReader może zakończyć się, zanim Twój Mainthread wykona metodę wait (), co spowoduje nieskończony sen Mainthread.

Rozwiązaniem obu powyższych problemów jest użycie zatrzasku. spróbuj CountDownLatch Zobacz poniżej

import java.util.concurrent.CountDownLatch;

MyClass klasy publicznej {

CountDownLatch latch = new CountDownLatch(1);

public MyClass(){

}

public void a() {
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("A: I am going to sleep");
System.out.println("A: I slept one full day. Feels great.");
System.out.println("A: Hey B, wake up!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}).start();
}

public void b() {
new  Thread(new Runnable(){
@Override
public  void run() {
System.out.println("B: I am  going to sleep. A, please wake me up.");
try {
latch.await();
} catch (InterruptedException e) {}
System.out.println("B: Thank you A for waking me up!");
}
}).start();
}

public static void main(String[] args) {
MyClass obj = new MyClass();
obj.a();
obj.b();
}

Powyższy kod pochodzi z mojej odpowiedzi na podobne pytanie