2010-10-14 14 views
5

Przeczytaj, że zakleszczenie może się zdarzyć w jednym wątku programu java. Zastanawiam się, skoro nie będzie żadnej konkurencji. O ile pamiętam, książki ilustrują przykłady z więcej niż jednym wątkiem. Czy możesz podać przykład, jeśli może się to zdarzyć z jednym wątkiem?Zakleszczenie w jednym wątku programu java

Odpowiedz

0

nr

piórowy wynikiem wielu nitek (lub procesy) próbować pozyskać blokady w taki sposób, że nie można kontynuować.

Rozważmy cytat z artykułu z Wikipedii: „Kiedy dwa pociągi zbliżają się do siebie na przejściu, zarówno przyjdzie do pełnego zatrzymania i nie powinien uruchomić się ponownie dopiero drugi upadł” (http://en.wikipedia.org/wiki/Deadlock)

+0

Wiele wątków lub * procesów * .... – NVRAM

+0

Dobry punkt Cartera. Zmieniłem swój komentarz. Dzięki. – philipk

+0

Tak, cóż, wiele (tj. Więcej niż 0) wątków, o tym właśnie mówimy. – Ingo

0

Nie, brzmi dla mnie całkiem niemożliwe.

Ale teoretycznie można zablokować zasób systemowy, podczas gdy inna aplikacja blokuje inną, o którą poprosisz, a ta poprosi o tę, którą już zablokowałeś. Bang Zakleszczenie.

System operacyjny powinien być w stanie rozwiązać problem, wykrywając to i przekazując oba zasoby do jednej aplikacji. Szanse na to są niewielkie, ale każdy dobry system operacyjny powinien być w stanie obsłużyć tę jedną na miliard szans.

Jeśli projekt zostanie wykonany starannie i blokuje tylko jeden zasób na raz, nie może się tak stać.

+0

Dlaczego upadek? Ta odpowiedź precyzyjnie omawia rzecz, która może się wydarzyć raz na miliard. – Frank

+0

Nie głosowałem, ale prawie to zrobiłem. Twój drugi akapit jest poprawny, a więc szansa na to wydarzenie jest bardzo wysoka, jeśli projekt aplikacji działa w opisany sposób. Tak więc twoja 3 para jest _wrong_ (dla większości zasobów w większości systemów operacyjnych). W końcu, ** dokładnie, co system operacyjny zrobiłby, aby uniknąć impasu? ** – NVRAM

+0

A twój trzeci akapit zakłada, że ​​aplikacja może osiągnąć swoje cele tylko z jednym zasobem, który po prostu nie działa dla ogromnej liczby problemów. – NVRAM

6

Chodzi o to, jak dokładnie definiujesz "zakleszczenie".

Na przykład ten scenariusz jest dość realistyczny: aplikacja jednowątkowa, która używa ograniczonej wielkością kolejki blokującej po osiągnięciu limitu. Dopóki limit nie zostanie osiągnięty, będzie działał dobrze z jednym wątkiem. Ale gdy limit zostanie osiągnięty, wątek będzie czekać na zawsze dla (nieistniejącego) innego wątku, aby odebrać coś z kolejki, aby mógł kontynuować.

+3

Nie sądzę, że to jest impas. Inaczej 'while while (true) {}' to impas – Bozho

+0

@Bozho To blok, nie zakleszczenie, ale 'while (true)' nie ma z tym nic wspólnego. – EJP

1

Więc śmiem powiedzieć tak

Jeśli próbujesz nabyć taką samą blokadę w tym samym wątku kolejno, to zależy od rodzaju zamka lub blokowanie wdrożenia czy sprawdza on, czy zamek został nabyty przez tego samego wątku. Jeśli implementacja tego nie sprawdza, masz zakleszczenie.

Dla synchronizacji jest to zaznaczone, ale nie mogłem znaleźć gwarancji na Semafor.

Jeśli używasz innego rodzaju zamka, musisz sprawdzić specyfikację, jak to się zachowuje!

Jak już wskazano, możesz blokować (inaczej niż w przypadku zakleszczenia) przez odczytywanie/zapisywanie w ograniczonym buforze. Na przykład piszemy rzeczy do szczelinowego bufora i odczytujemy je tylko w określonych warunkach. Kiedy nie możesz już wstawić, poczekaj, aż automat będzie wolny, co nie nastąpi, ponieważ sam wykonasz odczyt.

Tak więc przypuszczam, że odpowiedź powinna być twierdząca, choć nie jest to takie łatwe i zwykle łatwiejsze do wykrycia.

HTH

Mario

2

Przed procesory wielordzeniowe stały się tanie, wszystkie komputery stacjonarne miały procesory jednordzeniowe. Procesory jednordzeniowe działają tylko w wątku. Więc jak działa wielowątkowość? Najprostsza implementacja Javy będzie: Kod

thread1 za:

doSomething(); 
yield(); // may switch to another thread 
doSomethingElse(); 

kod thread2 za:

doSomething2(); 
yield(); // may switch to another thread 
doSomethingElse2(); 

ten nazywany jest spółdzielnia wielowątkowość - wszystko odbywa się tylko z 1 gwintem, a więc wielowątkowość było Sporządzono w Windows 3.1.

Dzisiejsza wielowątkowość nazywana wielowątkowością zapobiegawczą jest po prostu niewielką modyfikacją wielowątkowości współpracy, w której ta wydajność() jest wywoływana automatycznie od czasu do czasu.

Wszystko, co może zmniejszyć się do następujących interlacings:

doSomething(); 
doSomething2(); 
doSomethingElse2(); 
doSomethingElse(); 

czyli

doSomething(); 
doSomething2(); 
doSomethingElse(); 
doSomethingElse2(); 

I tak dalej ... Jesteśmy przekształcony kodu wielowątkowe do jednowątkowym kodu. Tak, tak, jeśli w programach wielowątkowych możliwy jest również zakleszczenie w jednowątkowym. Na przykład:

thread1:

queue.put(x); 
yield(); 

thread2:

x = queue.waitAndGet() 
yield(); 

Jest OK z tym przeplotu:

queue.put(x); 
x = queue.waitAndGet() 

Ale tutaj otrzymujemy zakleszczenia:

x = queue.waitAndGet() 
queue.put(x); 

Więc tak, zakleszczenia są możliwe w programach jednowątkowych.

+0

Bardzo dobry punkt –

+0

Czy za każdym razem nie doszło do impasu? – Frank

+0

Przy tych 2 'wątkach' i yield() stanie się to losowo, z nowoczesnymi systemami operacyjnymi (które nie używają yield(), ale z preemptive threading) to zadziała, z drugim rozwiązaniem single-threaded, deadlock stanie się za każdym razem, po prostu zamień moje metody "queue.xxxx()" odpowiednimi metodami z BlockingQueue. Wątek będzie myśleć, że czeka na inny wątek, podczas gdy on czeka na siebie. :-) – iirekm

1

Nawet jeśli twoje pliki java są jednowątkowe, nadal istnieją procedury obsługi sygnałów, które są wykonywane w innym wątku/kontekście niż główny wątek.

Tak więc, zakleszczenie może się zdarzyć nawet w przypadku rozwiązań jednowątkowych, jeśli/kiedy Java jest uruchomiona na Linuksie.

QED. -pbr

+0

+1 nie myślał o sygnałach! –

-1

To jest całkiem proste:

BlockingQueue bq = new ArrayBlockingQueue(1); 
bq.take(); 

będzie impasu.

+0

To nie jest zakleszczenie. To jest blok. – EJP

+0

@ Neppicking @ EJP. Wątek, który to robi, jest martwy. Tak łatwo. – Ingo

Powiązane problemy