Wskazówki, aby zapobiec impasom w Javie

Studiuję wątki i impasy Javy, Rozumiem przykłady impasu, ale zastanawiam się, czy istnieją ogólne zasady, których należy przestrzegać, aby temu zapobiec.

Moje pytanie brzmi, Czy istnieją zasady lub wskazówki, które można zastosować do kodu źródłowego w Javie, aby zapobiec impasom? Jeśli tak, czy mógłbyś wyjaśnić, jak to wdrożyć?

Author: djechlin, 2013-05-28

11 answers

Kilka szybkich porad z mojej głowy

    Nie używaj wielu wątków (jak Swing robi, na przykład, nakazując, że wszystko jest zrobione w EDT) Nie trzymaj kilku zamków na raz. Jeśli to zrobisz, zawsze kupuj zamki w tej samej kolejności
  • nie wykonuj kodu obcego trzymając blokadę
  • Użyj blokad przerywanych
 26
Author: JB Nizet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 21:51:59

Enkapsulować, enkapsulować, enkapsulować! prawdopodobnie najbardziej niebezpiecznym błędem, jaki możesz popełnić z zamkami, jest ujawnienie swojego zamka światu (upublicznienie go). Nie wiadomo, co może się zdarzyć, jeśli to zrobisz, ponieważ każdy byłby w stanie zdobyć blokadę bez wiedzy obiektu (dlatego też nie powinieneś blokować this). Jeśli zachowasz swój zamek prywatny, masz pełną kontrolę, a to sprawia, że jest on łatwiejszy do opanowania.

 11
Author: Despertar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-28 03:57:43
  1. unikaj blokad, używając bez blokad struktur danych (np. użyj ConcurrentLinkedQueue zamiast zsynchronizowanego ArrayList)
  2. zawsze nabywać zamki w tej samej kolejności, np. przypisać unikalną wartość liczbową do każdej blokady i nabywać zamki z niższą wartością liczbową przed nabyciem zamków z wyższą wartością liczbową
  3. Zwolnij blokady po upływie limitu czasu (technicznie nie zapobiega to blokadom, po prostu pomaga je rozwiązać po ich wystąpieniu)
 10
Author: Zim-Zam O'Pootertoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 21:51:08

Czytać i rozumieć Java: współbieżność i praktyka. Tu nie chodzi o "wskazówki", aby uniknąć impasu. Nigdy nie zatrudniłbym dewelopera, który znał kilka wskazówek, aby uniknąć impasu i często unikał impasu. Chodzi o zrozumienie współbieżności. Na szczęście istnieje obszerna książka na ten temat, więc idź ją przeczytać.

 7
Author: djechlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-10 21:49:39
    Nie używaj zamków. Jeśli musisz, trzymaj swoje zamki na miejscu. Globalne blokady mogą być naprawdę trudne. Zrób jak najmniej, kiedy przytrzymasz zamek.
  1. użyj pasków , aby zablokować tylko segmenty danych
  2. preferują typy niezmienne. Wiele razy oznacza to kopiowanie danych zamiast udostępniania danych.
  3. zamiast tego użyj mechaniki porównywania i ustawiania (CAS), Zobacz na przykład AtomicReference.
 6
Author: jontejj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 22:30:05

Biorąc pod uwagę wybór projektu, używaj przekazywania wiadomości tam, gdzie w kolejce push/pop znajdują się tylko blokady. Nie zawsze jest to możliwe, ale jeśli to możliwe, będziesz miał bardzo niewiele impasów. Nadal można je zdobyć, ale trzeba się naprawdę starać:)

 4
Author: Martin James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-28 00:29:09

Jest jedna wielka zasada, jeśli chodzi o zapobieganie impasom:

Jeśli potrzebujesz mieć wiele zamków w kodzie, upewnij się, że każdy zawsze nabywa je w tej samej kolejności.

Utrzymywanie kodu wolnego od zamków powinno być jednak zawsze twoim celem. Możesz spróbować pozbyć się ich za pomocą obiektów niezmiennych lub lokalnych wątków i bez blokad struktur danych.

 3
Author: Keppil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 21:51:01

Jest to klasyczny przykład impasu:

public void methodA(){

  synchronized(lockA){
  //...

   synchronized(lockB){
   //...
  }
 }
}

public void methodB(){

  synchronized(lockB){
  //...

   synchronized(lockA){
   //...
   }
  }
}

Te metody prawdopodobnie spowodowałyby Wielki impas, gdyby wywoływane były przez wiele wątków. Dzieje się tak dlatego, że obiekty są zamknięte w innej kolejności . Jest to jedna z najczęstszych przyczyn blokad, więc jeśli chcesz ich uniknąć, upewnij się, że zamki są wymagane w kolejności .

 2
Author: Asier Aranbarri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-27 22:30:50
  1. Unikaj zagnieżdżonych zamków. Jest to najczęstsza przyczyna impasu. Unikaj blokowania innego zasobu, jeśli już posiadasz one.It jest prawie niemożliwe, aby uzyskać impas, jeśli pracujesz tylko z jedną blokadą obiektu.

  2. Blokuj tylko to, co jest wymagane. Podobnie jak blokowanie określonego pola obiektu zamiast blokowania całego obiektu, jeśli służy to Twojemu celowi.

  3. Nie czekaj w nieskończoność.

 1
Author: 027,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-14 03:29:07
  1. Jeśli nie jest to wymagane, nie udostępniaj danych w wielu wątkach. Jeśli nie można zmienić danych po utworzeniu/inicjalizacji, należy trzymać się zmiennych końcowych.
  2. Jeśli nie możesz uniknąć współdzielenia danych między wieloma wątkami, użyj ziarnistych synchronized bloków lub blokad s.
  3. Jeśli używasz tylko synchronized bloków kodu, upewnij się, że blokady są nabywane/zwalniane w określonej kolejności.
  4. zwróć uwagę na inne alternatywy: zmienne lotne lub AtomicXXX zmienne lub Lock API

Podobne pytania SE:

Unikaj synchronizacji (tego) w Javie?

Różnica między lotnym a synchronizowanym w Javie

Volatile boolean vs AtomicBoolean

 1
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:18
  • Unikaj Zagnieżdżonych Zamków
  • Unikaj Zbędnych Zamków
  • Użyj wątku join ()
 1
Author: Arun Raaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-24 23:14:22