Co w tym kodzie oznaczają dwa łączenia i przerwy? t1.join()
powoduje t2
zatrzymanie do t1
zakończenia?
Thread t1 = new Thread(new EventThread("e1"));
t1.start();
Thread t2 = new Thread(new EventThread("e2"));
t2.start();
while (true) {
try {
t1.join();
t2.join();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
java
multithreading
user697911
źródło
źródło
while(true)
wywoływaćjoin
metody.Odpowiedzi:
Cytując z
Thread.join()
metody javadocs :Istnieje wątek, który uruchamia Twój przykładowy kod, który jest prawdopodobnie głównym wątkiem .
t1
it2
. Dwa wątki zaczynają działać równolegle.t1.join()
oczekiwanie na zakończeniet1
wątku.t1
finalizuje gwintu it1.join()
powraca metody z głównym gwintem. Zauważ, żet1
mogło to już zakończyć się przed wykonaniemjoin()
połączenia, w takim przypadkujoin()
połączenie powróci natychmiast.t2.join()
oczekiwanie nat2
wątku.t2
finalizuje wątek (lub może być zakończona, zanimt1
zrobił nić) it2.join()
powraca metoda w głównym wątku.Ważne jest, aby zrozumieć, że wątki
t1
it2
działały równolegle, ale główny wątek, który je rozpoczął, musi poczekać na zakończenie, zanim będzie mógł być kontynuowany. To powszechny wzorzec. Ponadto,t1
i / lubt2
mógł skończyć się przed wywołaniemjoin()
ich przez główny wątek . Jeśli tak, tojoin()
nie będzie czekać, ale wróci natychmiast.Nie. Główny wątek, który wywołuje
t1.join()
, przestanie działać i zaczeka na zakończeniet1
wątku.t2
Wątek jest uruchomiony równolegle i nie ma wpływut1
lubt1.join()
rozmowa w ogóle.Jeśli chodzi o try / catch,
join()
rzutyInterruptedException
oznaczają, że wywoływany wątek głównyjoin()
może sam zostać przerwany przez inny wątek.Łączenia w
while
pętli to dziwny wzór. Zazwyczaj pierwsze łączenie, a następnie drugie łączenie, obsługujeInterruptedException
odpowiednio w każdym przypadku. Nie ma potrzeby zapętlania ich.źródło
t1
it2
mogą działać równolegle. Chodzi tylko o to, żemain
oboje muszą skończyć, zanim będzie można kontynuować. To typowy wzorzec @ user697911.while
Pętla jest tam, bo (chyba), że chce, aby ponowić próbę zjoin()
połączenia jeśli zostanie przerwane? Na pewno nie napisałbym tego w ten sposób @ user697911.t1
it2
zakończą się. To znaczy. jeślit1
wyrzuciInterruptedException
, zapętli się i zaczeka nat2
. Alternatywą jest czekanie na oba wątki w każdym Try-Catch, aby uniknąć pętli. Ponadto, w zależności odEventThread
tego, może to mieć sens, ponieważ uruchamiamy 2 wątki, a nie jeden.To jest ulubione pytanie do wywiadu Java .
t1.join()
oznacza, że t1 mówi coś w stylu „ Chcę najpierw skończyć ”. To samo dotyczyt2
. Bez względu na to, kto rozpocząłt1
lubt2
wątek (w tym przypadkumain
metoda), main zaczeka nat1
it2
zakończy swoje zadanie.Jednak ważne jest, aby zanotować,
t1
at2
same mogą działać równolegle niezależnie od sekwencji łączenia połączeń nat1
it2
. Tomain/daemon
nić musi czekać .źródło
t1.join(); t2.join();
nie pozwoli wątkowi, który wykonuje łączenia, na kontynuowanie, dopóki oba wątki nie zostaną zakończone. W przypadku braku bardzo nietypowego kodu w innym miejscu, kolejność łączenia nie ma znaczenia.join()
oznacza oczekiwanie na zakończenie wątku. To jest metoda blokująca. Twój główny wątek (ten, który wykonujejoin()
) będzie czekał nat1.join()
linii, ażt1
zakończy swoją pracę, a następnie zrobi to samo dlat2.join()
.źródło
Obraz jest wart tysiąca słów.
Mam nadzieję, że przydatne, aby uzyskać więcej informacji, kliknij tutaj
źródło
Gdy wątek tA wywołuje funkcję tB.join (), powoduje to nie tylko oczekiwanie na śmierć tB lub przerwanie tA, ale także utworzenie relacji zdarzają się przed ostatnią instrukcją w tB i następną po tB.join () w wątku tA.
To znaczy program
Zawsze drukuj
Ale program
Może drukować nie tylko
Ale
Zawsze tylko „0”.
Ponieważ Java Memory Model nie wymaga „przenoszenia” nowej wartości „sharedVar” z wątkuB do głównego wątku bez relacji heppens-before (początek wątku, łączenie wątku, użycie słowa kluczowego „synchonized”, użycie zmiennych AtomicXXX itp.).
źródło
Mówiąc najprościej:
t1.join()
wraca pot1
zakończeniu.Nie robi nic w wątku
t1
, z wyjątkiem czekania na zakończenie.Oczywiście następujący kod
t1.join()
zostanie wykonany dopiero pot1.join()
zwrocie.źródło
Ze strony dokumentacji Oracle na temat połączeń
Jeśli t1 jest
Thread
obiektem, którego wątek jest aktualnie wykonywany,Jeśli t2 jest
Thread
obiektem, którego wątek jest aktualnie wykonywany,join
API to niskopoziomowe API, które zostało wprowadzone we wcześniejszych wersjach java. Wiele rzeczy zostało zmienionych przez pewien czas (szczególnie w wydaniu jdk 1.5) na froncie współbieżności.To samo można osiągnąć dzięki interfejsowi API java.util.concurrent. Oto niektóre przykłady
ExecutorService
Executors
(od wersji java 8)Zobacz powiązane pytania dotyczące SE:
poczekaj, aż wszystkie wątki zakończą swoją pracę w java
źródło
Dla mnie zachowanie Join () zawsze było mylące, ponieważ starałem się zapamiętać, kto będzie na kogo czekać. Nie próbuj o tym pamiętać w ten sposób.
Wszyscy wiemy, że gdy wywołujemy funkcję wait () na dowolnym obiekcie (t1), wywołanie obiektu (main) jest wysyłane do poczekalni (stan Zablokowany).
Tutaj główny wątek wywołuje join (), czyli wait () pod osłonami. Więc główny wątek będzie czekał, aż zostanie powiadomiony. Powiadomienie jest wysyłane przez t1, gdy zakończy swoje działanie (zakończenie wątku).
Po otrzymaniu powiadomienia main wychodzi z poczekalni i przystępuje do realizacji.
źródło
Mam nadzieję, że to pomoże!
źródło
powiedzmy, że nasz główny wątek rozpoczyna wątki t1 i t2. Teraz, gdy wywoływana jest funkcja t1.join (), główny wątek zatrzymuje się, aż wątek t1 umrze, a następnie sam się wznawia. Podobnie, gdy t2.join () jest wykonywana, główny wątek ponownie się zawiesza, aż wątek t2 umrze, a następnie zostanie wznowiony.
A więc tak to działa.
Ponadto pętla while nie była tutaj naprawdę potrzebna.
źródło