2011-11-25 17 views
8

W poniższym fragmencie kodu zadeklarowanie metody doThings() jako statycznej spowodowałoby, że klasa będzie bezpieczna dla wątków. Czy powodem jest to, że jeśli wiele wątków TestSeven zostanie uruchomionych, a x jest zmienną statyczną, to może wystąpić warunek wyścigu?Dlaczego ten kod nie jest bezpieczny dla wątków?

public class TestSeven extends Thread{ 

    private static int x; 

    public synchronized void doThings(){ 
     int current = x; 
     current++; 
     x = current; 
    } 

    public void run(){ 
     doThings(); 
    } 

    public static void main(String args[]){ 
     TestSeven t = new TestSeven(); 
     Thread thread = new Thread(t); 
     thread.start(); 
    } 
} 
+1

Przekaż testeeven, który jest wątkiem jako argument konstruktora wątków. Działa to, ponieważ wątek IS-A może zostać uruchomiony, ale nie jest zalecany, lepiej wykonać TestSeven implementuj Runnable –

Odpowiedz

15

Tak, dokładnie. Charakter synchronized powoduje jedynie, że nie jest on wywoływany przez wiele wątków jednocześnie z numerem w tej samej instancji. Zmienna x jest udostępniana na podstawie globalnej, a nie na podstawie poszczególnych wystąpień, dlatego jest niebezpieczna.

W ujęciu realnym świecie, pomyśl o tym jak o łazienka z kilku bram - ktoś może otworzyć jedne drzwi, a następnie zablokować go, ale to nie przeszkadza komuś z najbliższych poprzez inną drzwi ...

+1

Bardzo ładny przykład. – gprathour

+0

+1: blokowanie bieżącego wątku, co ma tu miejsce, prawie zawsze jest bezcelowe. –

+0

Bardzo dobre wytłumaczenie. Krótko, ale podsumowuje to ładnie. –

1

Myślę, że gdyby metoda nie była statyczna, każdy obiekt TestSeven zsynchronizowałby się przy użyciu własnego zamka - tak, że będzie jeden wątek na blokadę i żaden z nich nie będzie musiał czekać na kolejny wątek. Jeśli metoda jest zadeklarowana jako statyczna, wydaje mi się, że blokuje ona odpowiedni obiekt klasy.

1

Trzeba dodać, że jeśli zadeklarujesz metodę doThings static, zsynchronizuje ona blokadę klasy, a nie blokadę instancji, a następnie będzie kuloodporna.

1

tak. Może w tym wystąpić stan wyścigowy. Ponieważ czynisz metodę synchronizowaną, a nie zmienną. Zatem zgodnie z definicją warunków wyścigu, jeden wątek odczyta wartość zmiennej, podczas gdy inny w metodzie zsynchronizowanej może ją zapisać. Tak więc stan wyścigu będzie tam.

1

Synchronizujesz swój kod na this, co oznacza, że ​​wystąpienie TestSeven. x jest statyczny, więc nie będzie zablokowany. Dlatego z różnych instancji możesz uzyskać dostęp do tego samego x. Aby wykryć blokadę tego atrybutu, musisz zsynchronizować się na zajęciach.

Powiązane problemy