2011-06-22 34 views
8

Próbowałem synchronizować na obiekcie w moim kodu poniżej:NullPointerException na zsynchronizowanym rachunku

public void myMethod() { 
    synchronized (globalObj) { 
     //Do something here 
    } 
} 

kod jest wykonywany w jednym wątku. Problem polega na tym, że inny wątek może ustawić wartość "globalObj" na wartość null. Następnie "synchronized (globalObj)" spowoduje NullPointerxception, gdy "globalObj" został ustawiony na wartość null przez inne wątki.

Jaka jest najlepsza praktyka do synchronizowania obiektu, aby wyjątek NullPointerException nie został wygenerowany?

Dzięki.

+0

Więcej kodu proszę. –

Odpowiedz

25

Nie powinieneś synchronizować na podstawie odniesienia, które samo może zostać zmienione. Jeśli inny wątek może zastąpić globalObj, oznacza to, że możesz zablokować stary globalObj, podczas gdy inny wątek działa na zupełnie innym - blokada w ogóle ci nie pomoże.

Co należy zrobić, to zamiast mieć oddzielny Object do tego celu:

static final Object lockObj = new Object(); 

public void myMethod() { 
    synchronized (lockObj) { 
    // do something with globalObj here 
    } 
} 

Od lockObj nigdy się nie zmienia, zawsze będziesz korzystać z tego samego lock - żadnych problemów.

1

Upewnij się zsynchronizować na obiekcie, który nie może być null ...

Czemu ustawiania globalObj null? Jaka powinna być semantyka współbieżności? Czy to przez przypadek?

Jeśli konieczność zablokowania zniknie czasami (wydaje się dziwne), możesz dodać zerową kontrolę (oczywiście, musisz zsynchronizować coś innego, aby uniknąć stanu wyścigu z pierwszym sprawdzeniem zerowej wartości, a następnie po ustawieniu go na wartość null zaraz po tym).

Proszę opisać swój scenariusz bardziej szczegółowo.

0

Utwórz element klasy obiektu prywatnego, który nie ma żadnych publicznych ustawiaczy i zablokuj go.

6

Nie można synchronizować na podstawie odwołania null. Najlepszą metodą jest synchronizacja na obiekcie final (aby upewnić się, że nigdy nie jest to null), lub (jeszcze lepiej) użyj abstrakcji współbieżności wyższego poziomu w pakietach java.util.concurrent.

Powiązane problemy