Watki - synchronizacja za pomoca notify i wait

0

Siemka, ucze się własnie podstaw Wielowątkowości w Javie, jak zalapanie jak dziala FutureTask nie stworzył jakiegos większego problemu tak z niskopoziomowym wątkowaniem nie mogę sobie poradzić.
Napisałem coś takiego:

	static String czytnik;
	
	public static void main(String args[]) {
		Scanner scan = new Scanner(System.in);
		
		Thread reader = new Thread(){
			public void run(){
				while(true){
					synchronized(this){
						try {
							wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println(czytnik);
					}
				}
			}
		};
		Thread writter = new Thread(){
			public void run(){
				while(true){
					synchronized(this){
						czytnik = scan.nextLine();
						notify();
					}
				}
			}
		};
		
		writter.start();
		reader.start();
	}

Efekt jest taki, ze scanerem pobieram ciag znakow w jednym watku a w drugim wypisuje to co pobralem(czytnik), i tak na zmiane. Dlaczego lancuchy sie pobieraja ale nie zostaja wypisne?
dlaczego po odpaleniu tego nic mi się nie wypisuje?

0

Może trafiasz w taki przeplot:

  • reader zaczyna wykonywać pętlę główną, blokuje obiekt "this" i czeka na notydikację: wait();
  • Notyfikacja nie przychodzi, bo writter czeka na zwolnienie obiektu "this" (który jest zajęty przez readera)

Ogólnie z wait/notify trzeba ostrożnie, np. notify może zostać wygenerowane zanim wait() zostanie wykonane i drugi wątek nie doczeka się na notify...

2

Masz tu przynajmniej trzy błędy:

  1. synchronized(this) na każdym wątku osobno
  2. wait / notify bez wskazania obiektu - czyli na każdym wątku osobno
  3. notify wcale nie musi na nic czekać - czyli writer może wszystko przeczytać i jeśli źródło jest nieskończone - w najlepszym wypadku proces pominie niektóre linie

Zajrzyj tutaj:
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
http://www.programcreek.com/2009/02/notify-and-wait-example/
http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java/

0

Debugowanie Twoim przyjacielem, wrzucaj wszędzie logi w postaci```
System.out.println("...");

0

Trafiłeś w mój temat :) Does Java notify waiting threads implicitly?

Nie należy synchronizować na publicznych obiektach, w szczególności na obiektach typu Thread. Może się zdarzyć, że coś innego zsynchronizuje się na tym samym. Synchronizuj na czymś prywatnym, np. private Object lock.

1 użytkowników online, w tym zalogowanych: 0, gości: 1