Próbuję zrozumieć stan wątkuobiekt po zakończeniu wątku. Przeczytałem w książce, że po zakończeniu wątku przez metodę run () obiekt wątku nadal będzie prawidłowym obiektem na głowie i nadal może być używany jako obiekt instancji, a ty nadal możesz wywoływać na nim metody. Zdecydowałem się spróbować z następującym przykładem:
class DieThread implements Runnable{
int y = 0;
public void run(){
for(int x=0; x<100; x++){
System.out.println(" " + Thread.currentThread().getName());
System.out.println("y is " + y);
y++;
System.out.println("y is " + y);
}
}
}
class ZiggyTest2{
public static void main(String[] args){
DieThread d = new DieThread();
Thread a = new Thread(d);
Thread b = new Thread(d);
Thread c = new Thread(d);
a.start();
b.start();
c.start();
try{
a.join();
b.join();
c.join();
}catch(Exception e){
System.out.println(e);
}
System.out.println("Running C"s Run");
c.run();
}
}
main () czeka na zakończenie pozostałych 3 wątkówza pomocą join (). Następnie wywołuje metodę run () c, ale z jakiegoś powodu nie wypisuje niczego z metody run (). Oto kilka ostatnich wierszy wyniku po uruchomieniu powyższego programu.
y is 287
y is 287
y is 288
y is 289
Thread-1
Thread-0
y is 289
y is 289
y is 290
y is 291
Thread-1
Thread-0
y is 291
y is 291
y is 292
y is 293
Thread-1
Thread-0
y is 293
y is 293
y is 294
y is 295
Thread-0
y is 295
y is 296
Thread-0
y is 296
y is 297
Thread-0
y is 297
y is 298
Thread-0
y is 298
y is 299
Thread-0
y is 299
y is 300
Running C"s Run
Mimo że wątek się zakończył, spodziewałem się, że wartość y wyniesie 400 z powodu wywołania c.run ().
Jakieś pomysły?
Dzięki
Odpowiedzi:
1 dla odpowiedzi № 1Powód tego, co obserwujesz, jest zakopany we wdrażaniu Thread
klasa.
Kiedy zadzwonisz c.run()
dzwonisz do run
metoda na obiekcie wątku. Jest to określone jako wywołanie run
metoda target
obiekt (tj. uruchamialny dostarczony w pliku Thread
konstruktor), jeśli nie jest null
. Jeśli target
jest null
a później Thread.run()
metoda nic nie robi.
OK, więc podałeś wartość inną niż null target
.
W rzeczywistości, gdy: Thread
wykończenia Thread.exit()
wywoływana jest metoda czyszczenia. Jedną z rzeczy, które robi czyszczenie, jest przypisanie null
do target
. (Kod zawiera komentarz dotyczący koniecznościagresywnie usuwaj referencje i identyfikator błędu. Niestety brakuje odpowiedniego raportu o błędzie, więc nie można poznać prawdziwych powodów, dla których to robią.)
W każdym razie podstawową kwestią jest to, że nie można „ponownie uruchomić obiektu docelowego” run()
metoda przez wywołanie Thread.run()
. Ale możesz wywołać obiekt docelowy run()
metoda bezpośrednio ... jeśli masz odwołanie do celu.
3 dla odpowiedzi № 2
Jeśli rozszerzysz klasę Thread, to zadziała. Teraz sprawdza Runnable
cel, który jest null
po Thread.exit ()
1 dla odpowiedzi nr 3
Synchronizuj dostęp do stanu obiektu DieThread
synchronized(this) {
System.out.println(" " + Thread.currentThread().getName());
System.out.println("y is " + y);
y++;
System.out.println("y is " + y);
}