2013-03-02 13 views

Odpowiedz

18

Ten kod nie jest bezpieczny wątku. Metoda instancji zsynchronizuje się na instancji, jeśli masz wiele instancji, nie będą używać tego samego monitora, a zatem aktualizacje mogą się przeplatać.

Musisz usunąć statyczne z pola value lub dodać statyczne do metody increment().

Ponadto, ponieważ publicznie wprowadzono value, istnieje dodatkowy problem, że wartość tę można zmienić lub przeczytać poza tą metodą, bez korzystania z synchronizacji, która mogłaby spowodować odczytanie starych wartości.

Więc zmienia swój kod poniżej uczyni to bezpieczny wątku:

public class IncreaseTest { 
    private int value = 0; 

    public synchronized int increment() { 
     return value++; 
    } 
} 
+0

(+1) Dobra uwaga. Całkowicie przeoczyłem "statyczne". – NPE

+0

@NPE Tak też początkowo. –

+0

prywatna wartość int = 0; // jeśli usuniesz statyczne i zmienisz publiczne na prywatne, czy ten wątek będzie bezpieczny? – codeisee

0

Jeśli używasz tej metody w dwóch wątków następnie trzeba zrobić lotną słowa kluczowego. Bez tego inny wątek może nie uzyskać najbardziej aktualnej wartości. (C#)

+0

Zsynchronizowane słowo kluczowe w deklaracji metody jest takie samo jak posiadanie 'lock (this) {...}' w C#. –

1

nie sądzę, to jest wątek bezpieczne, ponieważ zmienna statyczna jest jawne i mogą być dostępne przez innych wątków w sposób nie- bezpieczny sposób wątku. Aby być bezpieczeństwo wątków należy zadeklarować zmienną w następujący sposób:

public static volatile int value; 

Teraz value są lotne, są dostępne w zsynchronizowany bloku będzie.

+0

Tworzenie zmiennej zmiennej jest inne niż dostęp do niej z bloku synchronicznego. Działanie ++ nadal nie jest operacją atomową, nawet jeśli zmienna jest niestabilna. –

+0

"Dostęp do zmiennej działa tak, jakby był zamknięty w zsynchronizowanym bloku, zsynchronizowany sam ze sobą." według [this] (http://www.javamex.com/tutorials/synchronization_volatile.shtml) – niculare

+3

Porównanie w artykule jest złe, podatne na błędy.W szczególności "wartość ++" powoduje dwa różne wartości dostępu: jeden do odczytania wartości, a drugi do zapisu. Ustanowienie 'value' volatile nie zapewni, że odczyt i zapis są zawarte w pojedynczej, atomowej operacji. Zapewnia to tylko synchronizacja. Oznacza to, że można równolegle odczytać dwa wątki, a następnie pisać równolegle, a wartość będzie zwiększana o 1 zamiast zwiększać o 2. –

0

Powinieneś raczej użyć atomicvars

+0

Atomowe warianty nie są próżni dla problemów z wątkami per se. IMHO lepiej zrozumieć, co dzieje się pod maską. –

Powiązane problemy