2010-11-19 6 views
5

widzę to:Czy to jest w porządku? Zsynchronizowane (gwint), a następnie wkręcić = null w synchronizacyjnego bloku

// thread is a member of this class 

synchronized(this.thread) 
{ 
    this.thread.running = false; 
    this.thread.notifyAll(); // Wake up anything that was .waiting() on 
    // the thread 
    this.thread = null; // kill this thread reference. 
    // can you do that in a synchronized block? 
} 

Czy to jest ok aby ustawić thread=null zachowując blokadę na nią?

Znalazłem ten samorodek w odrobinie kodu BB.

+1

Czy jest jakiś powód, dla którego nie używasz Thread.interrupt(), ponieważ jest to obsługiwane przez biblioteki bazowe? –

Odpowiedz

7

Tak, w porządku. Zsynchronizowane oświadczenie wykona kopię odnośnika, który blokuje, i użyje kopii do ustalenia, co odblokować na końcu.

Section 14.19 z języka Java Specification rzeczywistości nie jest jasne, o tym, ale to robi państwo, że wyrażenie jest oceniany na początku - i nie wspominając oceniając go ponownie później.

+0

Jest w porządku, ale jest wątpliwe, czy ustawienie odwołania do wątku na wartość null jest dobrym pomysłem. – Adamski

+1

@Adamski: Zasadniczo bardzo rzetelnie postrzegam to, co synchronizuję, mówiąc szczerze - myślałem, że będę tego unikać :) –

+0

Zgoda - W rzeczywistości IntelliJ ostrzega mnie w tej sytuacji o synchronizacji na zmienna nieostateczna. – Adamski

3

Jest różnica:

synchronized(this.thread) 

możliwość synchronizacji na obiekcie Pole this.thread punkty

this.thread = null; 

Jesteś realokacja pole. Nic nie robisz z obiektem wymienionym powyżej, więc blokada jest nadal ważna.

0

Możesz to zrobić, ale prawie pewne jest, że kod jest błędny, niezależnie od tego, co próbuje osiągnąć. Opublikuj cały kod i gwarantuję, że jest oczywiste, że programista nie rozumie współbieżności.

Nie zmieniaj przypisania zmiennej używanej do synchronizacji.

0

Masz problem tylko, jeśli masz blok, który przypisuje nową wartość do wątku. W takim przypadku masz warunek wyścigu, ponieważ dwa bloki nie blokują tego samego obiektu, ale zaktualizują to samo pole i będą losowe co do tego, który blok przypisuje wartość jako ostatnią.

1

Zsynchronizowane wyrażenie jest dereferencji na wpis, więc każdy późniejszy użytkownik tej blokady otrzyma wyjątek NullPointerException. Możesz obejść to, umieszczając zerową kontrolę przed zsynchronizowanym blokiem, ale wtedy wprowadziłeś warunek wyścigu.

+0

"Oceniane" przy wpisie. – EJP

+3

@EJP więcej niż oceniano - wyrażenie, które zwraca wartość NULL, nie powoduje wyjątku NullPointerException. –

Powiązane problemy