Wywołanie Thread.join w wątku mającym Lock

Odpowiedz Nowy wątek
2019-01-05 07:27
0

Witam

Staram się ogarnąć coś ze współbieżności javy i tworzę różne mało użyteczne przykłady w celach dydaktycznych. Mam takie pytanie do przykładu który zamieściłem poniżej: Dlaczego Thread viewer nie wywołuje się w wątku t4 który ma założony lock? Wcześniej na wszelki wypadek zdejmuje ten lock ale i tak nie pomaga.Komunikaty na konsoli nie wskazują aby inny wątek niż viewer przejmował wtedy blokadę. W programie jeden wątek inkrementuje zmienną a drugi ją dekrementuje.

`
public class WspoldzielenieZasobow {

static volatile int d = 0;
static volatile boolean flag = false;

public static void main(String[] args) {

     final Lock lock = new ReentrantLock();

      Thread viewer = new Thread() {
            @Override public void run() {
                while(true) {
                System.out.println(d);
                try {
                Thread.sleep(1000);
                }
                catch(InterruptedException e) {
                    System.out.println(e);
                }
                }
            }
        };

     Thread t3 = new Thread() {
        @Override public void run() {
            boolean isLock = false;
            while(true) {
            if( !flag && (isLock = lock.tryLock())) {
                try {
                    System.out.println("Wywolanie t3");
                    d++;
                    flag = true;
                }
                finally {
                    if(isLock) 
                        lock.unlock();
                    Thread.yield();
                }
            }
            }
        }
     };

        Thread t4 = new Thread() {
        @Override public void run() {
            boolean isLock = false;
            while(true) {
            if( flag && (isLock = lock.tryLock())) {
                try {
                    System.out.println("Dekrementacja t4: " + (--d));
                    flag = false;
                try {
                System.out.println("Proboa wywolania viewer.join()");
                lock.unlock();
                viewer.join();
                lock.lock();

                Thread.sleep(1000);
                }
                catch(InterruptedException e) {
                    System.out.println(e);
                }
                }
                finally {
                    if(isLock) 
                        lock.unlock();
                    Thread.yield();
                }
            }
            }
        }
     };

        t3.start();
        t4.start();

}
}
`

edytowany 3x, ostatnio: Kuben, 2019-01-05 07:30

Pozostało 580 znaków

2019-01-05 12:00
0

Thread.join() nie wywołuje innych wątków. Czeka aż wątek będzie martwy.

Pozostało 580 znaków

2019-01-05 12:08
0

Czyli powinienem najpierw wywołać viewer.start() a poźniej viewer.join()? Tylko że to nadal nie chce działać :(

Pozostało 580 znaków

2019-01-05 12:10
0

Wątek wywołujący viewer.join() czeka do śmierci wątku viewer.

edytowany 1x, ostatnio: Delor, 2019-01-05 12:13

Pozostało 580 znaków

2019-01-05 13:21
0

W "Thinking in Java" czytam: "Wątek może wywołać metodę join() innego wątku, co sprawi, że realizacja wątku wywołującego zostanie wznowiona dopiero po zakończeniu wątku, którego metoda join() została wywołana. Jeśli jeden wątek wywoła metodę t.join() innego wątku t, to realizacja wątku wywołującego zostanie wstrzymana aż do czasu zakończenia wątku t."

W z tego co zrozumiałem to wątkiem wywołującym w moim programie jest t4 i wywołuje on metodę join() wątku viewer. Tym samym wątek t4 powinien zostać zawieszony i poczekać na realizację wątku viewer.

Pozostało 580 znaków

2019-01-05 13:33
0

I dokładnie tak robi.

i poczekać na realizację wątku viewer.

Czyli poczekać na zakończenie wątku viewer.

Pozostało 580 znaków

2019-01-05 14:30
0

No tak, ale wątek viewer nie realizuje swojego zadania ponieważ ma wyświetlić zmienną d a tego nie robi :( Przepraszam za upierdliwość ale zależy mi by to zrozumieć.

Pozostało 580 znaków

2019-01-05 14:48
1

Jak uruchomisz wątek viewer (viewer.start()) to wątek będzie realizował swoje zadanie (wypisywał coś na ekran).
Zakończy się gdy dojdzie do końca metody viewer.run() (przy while(true) ciężko o to).
viewer.join() czeka na koniec, a nie realizację wątku.

edytowany 1x, ostatnio: Delor, 2019-01-05 14:50

Pozostało 580 znaków

2019-01-05 15:23
0
Delor napisał(a):

Jak uruchomisz wątek viewer (viewer.start()) to wątek będzie realizował swoje zadanie (wypisywał coś na ekran).
Zakończy się gdy dojdzie do końca metody viewer.run() (przy while(true) ciężko o to).
viewer.join() czeka na koniec, a nie realizację wątku.

Z tego co mówisz wynika że program nie może się nigdy skończyć, no bo w viewer jest while(true) a t4 czeka na jego zakończenie, tak?

Pozostało 580 znaków

2019-01-05 15:28
0
Kuben napisał(a):
Delor napisał(a):

Jak uruchomisz wątek viewer (viewer.start()) to wątek będzie realizował swoje zadanie (wypisywał coś na ekran).
Zakończy się gdy dojdzie do końca metody viewer.run() (przy while(true) ciężko o to).
viewer.join() czeka na koniec, a nie realizację wątku.

Z tego co mówisz wynika że program nie może się nigdy skończyć, no bo w viewer jest while(true) a t4 czeka na jego zakończenie, tak?

:Okej teraz zadziałało, przyczyną całego niedziałania programu był brak viewer.start(). Myślałem że join spowoduje wywołanie wątku. Dzięki za pomoc :)

Pozostało 580 znaków

2019-01-05 15:33
0

A jeszcze mam pytanie z innej beczki: Dlaczego nie trzeba zdejmować blokady Lock przy wywołaniu viewer.join()? Spróbowałem bez unlocka i też działa. W końcu wywołanie viewer przerywa prace t4... Czym jest de facto blokada tutaj? Czy w tym kontekście jest to działania na zasadzie Thread.sleep, czyli udostępnienie z całego czasu przydzielonego na wykonanie zadania t4.run fragmentu czasu na wywołanie viewer?

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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