2011-07-05 7 views
10

Od kiedy zacząłem programować w Javie, zastanawiałem się nad tym (około roku lub dwóch). W języku C musimy znać inną metodę, aby poprawnie uniknąć zakleszczenia między wątkami, a zatem istnieje znacznie większy wybór między metodą synchronizacji.Jak działa funkcja synchronizacji w java?

A co z Java? Kiedy synchronizujemy, jak uniknąć sytuacji, w której wątek znajduje się w sytuacji zakleszczenia? Jak to działa wewnętrznie? Czy można uniknąć zakleszczenia, ponieważ synchronizowaliśmy na wyższym poziomie niż w C (lub C++)? Wszelka dokumentacja dotycząca zakleszczenia i synchronizacji w java?

Odpowiedz

0

Musisz także zadbać o zakleszczenia w Javie. Najłatwiejszym sposobem uzyskania zakleszczenia jest spowodowanie, aby jeden wątek uruchomił blok synchronizowany na A, a następnie kolejny blok synchronizowany na B, podczas gdy inny wątek wykonuje blok synchronizowany na B, a następnie blok synchronizowany na A.

Czytaj the Java tutorial about concurrency. A jeśli chcesz się uczyć, przeczytaj Java concurrency in practice.

1

Synchronizacja nie jest to, że o wiele łatwiej w Javie niż w C. składniowo łatwiej, bo wszystko, co trzeba zrobić dla mutex jest zadeklarować metody jako zsynchronizowane lub użyj

synchronized(someObject) 
{ 
    someCode(); 
} 

natomiast w C/C++, musisz użyć funkcji specyficznych dla systemu operacyjnego, aby użyć muteksu, lub musisz użyć biblioteki Boost.

Ale pułapki na temat impasu są w zasadzie takie same jak w jakimkolwiek języku.

+0

Dziękujemy! Ale co dokładnie jest zsynchronizowanym słowem kluczowym, jest to muteks? I na platformie różnej, skoro wątki mogą być różne, czy będzie też inaczej? – Zonata

+2

To muteks. Muteks wprowadzający ponownie. –

0

Czy próbowałeś google (Java Deadlock)? Pierwszy wynik jest następujący: http://download.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

Widać, że z synchronized nadal występują zakleszczenia, ponieważ synchronizacja nie została zaprojektowana, aby zapobiec tym pierwszym.

+0

Cóż, moje pytanie nie dotyczy tylko impasu. Wiem, co to jest impas i znam większość dobrze znanego problemu (kolację filozofów, itp.). Chodzi również o wewnętrzną funkcjonalność zsynchronizowanego słowa kluczowego. Chcę poznać więcej szczegółów o tym, jak to działa. – Zonata

+0

@Zonata Czy wtedy zobaczyłeś dokumenty Oracle dotyczące synchronizacji? To tylko rozdział przed częścią impasu, którą połączyłem. Odpowiedź była przede wszystkim dostosowana do tego pytania: "Kiedy dokonujemy synchronizacji, w jaki sposób unika się wprowadzania wątku w sytuacji zakleszczenia?" - Nie działa. – Thomas

5

Głównym problemem, z którym spotykamy się z wielowątkowym kodem, jest udostępnianie danych, a ja zgadzam się z celem procesu paraliżowania konkurencyjności i "dzieje się to" w sposób "spokojny", że podczas paraliżowanego przetwarzania wątki wymagają dostępu do odczytu/zapisu na udostępnione dane.

Java zsynchronizowane słowa kluczowego dopuszcza następujące:

Mówi JVM umieścić blokadę na monitorze obiektu lub kawałek zsynchronizowanego kodu, co daje mu wyłącznego dostępu do tej części kodu lub obiektu .

Oto przykład Singleton:

public class Singleton { 
    private Singleton INSTANCE; 

    private Singleton() { 
    } 

    public Singleton getInstance() { 
     if (null == INSTANCE) { 
      INSTANCE = new Singleton(); 
     } 
     return INSTANCE; 
    } 
} 

Ten Singleton nie jest wątek bezpieczny, jeśli wątek próbuje dostać instancji, podczas gdy inny jest również stara się zrobić to samo (warunek race) to może się zdarzyć, że przedtem wątek numer jeden zakończy tworzenie instancji, drugi już miał dostęp do metody getInstance() i stworzył własną instancję Singleton, co oznacza, że ​​w czasie T powinniśmy mieć dwa wystąpienia Singleton (zwane multiton w tym czasie).

Aby rozwiązać ten problem, musimy synchronizować kreacyjnych zachowanie Singleton, może to być wykonane przez kluczowych synchronized powyżej if na sobie INSTANCE:

public class Singleton { 
    private Singleton INSTANCE; 

    private Singleton() { 
    } 

    public Singleton getInstance() { 
     synchronized (Singleton.class) { 
      if (null == INSTANCE) { 
       synchronized(Singleton.class) { 
        Singleton inst = new Singleton(); 
        INSTANCE = inst; 
       } 
      } 
     } 
     return INSTANCE; 
    } 
} 

W rezultacie, gdy pierwszy wątek prosi instancję Singleton i podczas tworzenia JVM zablokuje monitor INSTANCE odmawiając dostępu do INSTANCJI, aż wątek jeden zakończy jego żądanie.

Istnieją różne sposoby, aby to osiągnąć, cytowana wcześniej książka jest doskonałym źródłem nauki, javadoc również.

1

Krótkie odpowiedzi:

  1. synchronized metody i lock bloki użyć monitora że blokuje semafora z zablokowanym obiekcie w czasie trwania metody lub bloku.

  2. Sam język Java nie zapobiega zakleszczeniom. To zależy od Ciebie jako programisty, aby upewnić się, że obiekty są zablokowane/odblokowane w odpowiedniej kolejności, aby zapobiec rywalizacji.

0

Widzę problem z Singleton powyżej. Myślę, że klasa nigdy nie zostanie stworzona. Proszę rozważyć poniższy kod.

public class Singleton { 
    private static Singleton INSTANCE; 
    private Singleton() {  } 
    public static Singleton getInstance() { 
     synchronized (Singleton.class) { 
      if (null == INSTANCE) { 
       synchronized(Singleton.class) { 
        Singleton inst = new Singleton(); 
        INSTANCE = inst; 
        } 
      } 
     } 
     return INSTANCE; 
    } 
} 
+1

Dlaczego klasa nie została stworzona kiedykolwiek? –