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 15:36
0

W viewer nie sprawdzasz blokady.

Pozostało 580 znaków

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

W viewer nie sprawdzasz blokady.

Aha czyli gdybym dodał tam sekcje if( lock.tryLock()) to wtedy viewer mógłby nie zrealizować zadania? A w przeciwnym razie blokada go nie obowiązuje, więc może działać kiedy chce?

edytowany 1x, ostatnio: Kuben, 2019-01-05 15:40

Pozostało 580 znaków

2019-01-05 15:51
0

Dokładnie.

Pozostało 580 znaków

2019-01-05 16:15
0

Ok a załóżmy że zamiast jawnej blokady byłby tam blok synchronized. Rozumiem to tak, że wtedy wywołanie viewer.join nie powoduje zdjecia blokady t4, jedynie wywołujący wątek, który posiada aktualnie blokadę (tutaj t4) użycza czasu procesora dla wywołania zewnętrznego wątku i wznowi działanie gdy ten wątek sie zakończy. Blokada zostanie zdjęta dopiero po całkowitym zakończeniu t4. Do tego czasu nie może działać żaden wątek poza tymi, które zostały wywołane przez t4. Dobrze to sobie tłumacze?

Pozostało 580 znaków

2019-01-05 16:27
0

Zależy na czym będziesz miał ten blok synchronized. Blokada będzie zdjęta po wyjściu z bloku.

Pozostało 580 znaków

2019-01-05 16:42
0

Zależy na czym? No np. tak jak w zamieszczonym przeze mnie przykładzie, tylko zamiast Lock. Są jakieś szczególne przypadki pozbawienia wątku blokady przed wyjściem z synchronized?

Pozostało 580 znaków

2019-01-05 17:30
0

Synchronized robisz na obiekcie. Na czym będzie w Twoim przykładzie? Na obiekcie lock? To będzie działać identycznie.
Z tym że z wątek z blokadą na Lock możesz przerwać (interupt()) a z blokadą synchronized nie możesz.

edytowany 1x, ostatnio: Delor, 2019-01-05 17:38

Pozostało 580 znaków

2019-01-05 20:45
0
Delor napisał(a):

Synchronized robisz na obiekcie. Na czym będzie w Twoim przykładzie? Na obiekcie lock? To będzie działać identycznie.
Z tym że z wątek z blokadą na Lock możesz przerwać (interupt()) a z blokadą synchronized nie możesz.

Miałem na myśli blokadę na this po prostu. Nie rozumiem po co robić blokadę na obiekcie lock... Blokadę robi się na obiekcie którego metody będzie się wywoływać, zgadza się? Lock de facto do niczego już nie jest potrzebny jeśli używamy bloku synchronized.

Pozostało 580 znaków

2019-01-05 21:07
0

Dla każdego run() this jest innym obiektem.

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