2010-10-14 14 views
5

Ce blocage peut se produire dans un programme java à un seul thread. Je me demande comment, puisqu'il n'y aura pas de concurrence après tout. Autant que je me souvienne, les livres illustrent des exemples avec plus d'un fil. Pouvez-vous s'il vous plaît donner un exemple si cela peut arriver avec un seul fil.Blocage dans un programme java à un seul thread

Répondre

0

n °

Deadlock est le résultat de plusieurs threads (ou processus) qui tentent d'acquérir des verrous de telle sorte que ni peut continuer.

Tenir compte une citation de l'article de Wikipedia: (http://en.wikipedia.org/wiki/Deadlock)

« Lorsque deux trains se rapprochent à un croisement, les deux doivent venir à un arrêt complet et ne commence à nouveau jusqu'à ce que l'autre a disparu. »

+0

Plusieurs threads ou * processus * .... – NVRAM

+0

Bon point Carter. J'ai modifié mon commentaire. Merci. – philipk

+0

Oui, eh bien, plusieurs threads (c'est-à-dire plus de 0), c'est de cela que nous parlons. – Ingo

0

Non, cela me semble assez impossible.

Mais vous pouvez théoriquement verrouiller une ressource système alors qu'une autre en verrouille une autre que vous allez demander et que cette application va demander celle que vous avez déjà verrouillée. Bang Impasse.

Mais le système d'exploitation devrait être en mesure de trier cette chose en détectant cela et donner les deux ressources à une application à la fois. Les chances que cela se produise sont minces à aucun, mais tout bon OS devrait être capable de gérer cette chance sur un milliard.

Si vous réalisez la conception avec soin et ne verrouille qu'une seule ressource à la fois, cela ne peut pas se produire.

+0

Pourquoi la downvote? Cette réponse est exacte, discutant d'une chose qui pourrait arriver une fois sur un milliard. – Frank

+0

Je n'ai pas voté bas, mais j'ai failli le faire. Votre 2e paragraphe est correct, par conséquent les chances que cela se produise sont très élevées si la conception de l'application (s) fonctionne de la manière que vous décrivez. Donc votre 3ème para est _wrong_ (pour la plupart des ressources sur la plupart des OS). Après tout, ** exactement ce que le système d'exploitation fait pour éviter l'impasse? ** – NVRAM

+0

Et votre 3e paragraphe suppose que l'application peut atteindre ses objectifs avec une seule ressource, ce qui ne fonctionne tout simplement pas pour un grand nombre de problèmes. – NVRAM

6

Il s'agit de savoir exactement comment vous définissez "deadlock". Par exemple, ce scénario est quelque peu réaliste: une application monothread qui utilise une file d'attente à taille limitée qui bloque lorsque sa limite est atteinte. Tant que la limite n'est pas atteinte, cela fonctionnera correctement avec un seul thread. Mais lorsque la limite est atteinte, le thread attendra toujours qu'un autre thread (non existant) prenne quelque chose dans la file d'attente pour qu'il puisse continuer.

+3

Je ne pense pas que ce soit une impasse. Ou alors 'while (true) {}' est une impasse – Bozho

+0

@Bozho C'est un bloc, pas une impasse, mais 'while (true)' n'a rien à voir avec ça. – EJP

1

Eh bien, j'ose dire oui

Si vous essayez d'acquérir le même verrou dans le même fil consécutivement, cela dépend du type de verrouillage ou de verrouillage mise en œuvre si elle vérifie si le verrou est acquis par le même fil. Si la mise en œuvre ne vérifie pas cela, vous avez un blocage.

Pour synchronisé ceci est vérifié, mais je n'ai pas trouvé la garantie pour Semaphore.

Si vous utilisez un autre type de verrou, vous devez vérifier la spécification comme comment il est garanti de se comporter!

Comme cela a déjà été souligné, vous pouvez bloquer (ce qui est différent de l'interblocage) en lisant/écrivant dans un tampon restreint. Par exemple, vous écrivez des choses dans un tampon fendu et vous en lisez seulement certaines conditions. Quand vous ne pouvez plus insérer, vous attendez qu'une fente soit libre, ce qui n'arrivera pas puisque vous faites vous-même la lecture.

Donc, je dois dire que la réponse devrait être oui, mais pas si facile et généralement plus facile à détecter.

HTH

Mario

2

Avant processeurs multi-cœurs sont devenus pas cher, tous les ordinateurs de bureau ont des processeurs à cœur unique. Les processeurs monocœur s'exécutent uniquement sur le thread. Alors, comment le multithreading a fonctionné alors? La mise en œuvre plus simple pour Java serait:

Code de thread1:

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

Code de thread2:

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

Ceci est appelé coopérative multithreading - tout est fait avec seulement 1 fil, et ainsi multithreading était fait dans Windows 3.1.

Le multithreading d'aujourd'hui appelé multithreading préemptif est juste une légère modification du multithreading coopératif où ce yield() est appelé automatiquement de temps en temps.

Tout ce qui peut réduire les entrelacements suivants:

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

ou:

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

Et ainsi de suite ... Nous avons converti le code multithread seul code-thread. Donc oui, si un blocage est possible dans les programmes multithread dans un seul thread. Par exemple:

thread1:

queue.put(x); 
yield(); 

thread2:

x = queue.waitAndGet() 
yield(); 

Il est OK avec ce entrelacent:

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

Mais nous obtenons une impasse:

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

Alors oui, les interblocages sont possibles dans les programmes mono-thread.

+0

Très bon point –

+0

Cette impasse ne se produirait-elle pas à chaque fois? – Frank

+0

Avec ces 2 'threads' et yield() cela arrivera au hasard, avec des systèmes d'exploitation modernes (qui n'utilisent aucun yield() mais threading préemptif) ça fonctionnera, avec la deuxième solution monothread, un deadlock arrivera à chaque fois, remplacez mes méthodes 'queue.xxxx()' par des méthodes appropriées de BlockingQueue. Le thread pensera qu'il attend un autre thread, alors qu'il attend lui-même. :-) – iirekm

1

Même si votre tâche Java est monothread, il y a toujours des gestionnaires de signaux, qui sont exécutés dans un thread/contexte différent du thread principal. Par conséquent, un blocage peut se produire même sur des solutions monothread, si/quand java s'exécute sous linux.

QED. -pbr

+0

+1 ne pensait pas aux signaux! –

-1

Il est en fait assez simple:

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

sera une impasse.

+0

Ce n'est pas une impasse. C'est un bloc. – EJP

+0

@EJP Nitpicking. Le fil qui fait cela est mort. Si facile. – Ingo