web-dev-qa-db-fra.com

Différence entre les états de thread WAIT et BLOCKED

Quelle est la différence entre l'état du thread WAIT et l'état du thread BLOCKED?

La documentation Thread.State :

Bloqué
Un thread bloqué dans l'attente d'un verrouillage du moniteur se trouve dans cet état.

Attendre
Un thread qui attend indéfiniment qu'un autre thread effectue une action particulière est dans cet état

ne m'explique pas la différence.

74
More Than Five

Un thread passe à l'état d'attente une fois qu'il a appelé wait() sur un objet. Cela s'appelle Waiting State . Une fois qu'un thread a atteint l'état d'attente, il doit attendre qu'un autre thread notify() ou notifyAll() sur l'objet.

Une fois que ce thread est notifié, il ne sera pas exécutable. Il se peut que d’autres threads soient également notifiés (avec notifyAll()) ou que le premier thread n’ait pas terminé son travail. Il est donc toujours bloqué tant qu’il n’a pas eu sa chance. Ceci s'appelle Bloqué Etat.

Une fois que les autres threads sont partis et qu’il a cette chance, il passe à l’état Runnable après qu’il constitue un travail de ramassage éligible basé sur le mécanisme de thread JVM et passe à l’état d’exécution.

54
Ankit Bansal

La différence est relativement simple.

Dans l'état BLOCKED, un thread est sur le point d'entrer un bloc synchronized, mais un autre thread est en cours d'exécution dans un bloc synchronized sur le même objet. Le premier thread doit ensuite attendre que le second thread quitte son bloc.

Dans l'état WAITING, un thread attend un signal d'un autre thread. Cela se produit généralement en appelant Object.wait() ou Thread.join(). Le thread restera alors dans cet état jusqu'à ce qu'un autre thread appelle Object.notify() ou meure.

68
Flavio

La différence importante entre les états bloqué et d'attente est l'impact sur le planificateur. Un thread dans un état bloqué fait partie d'un groupe d'attente en concurrence pour un verrou; ce thread compte toujours comme quelque chose que l'ordonnanceur a besoin de gérer, éventuellement pris en compte dans les décisions de l'ordonnanceur concernant le temps imparti aux threads en cours d'exécution. 

Une fois qu'un thread est dans l'état d'attente, le stress qu'il impose au système est minimisé et le planificateur n'a pas à s'en soucier. Il reste en veille jusqu'à ce qu'il reçoive une notification. Hormis le fait qu'il occupe un thread OS, il est totalement hors-jeu.

C’est pourquoi utiliser notifyAll n’est pas idéal, cela provoque un tas de threads qui étaient auparavant en sommeil et qui n’engendrent aucune charge sur le système, mais la plupart d’entre eux se bloqueront jusqu’à ce qu’ils puissent obtenir le verrou, trouver la condition qu’ils sont attendre n'est pas vrai, et recommencez. Il serait préférable de ne notifier que les threads qui ont une chance de progresser. 

(Utiliser ReentrantLock au lieu de verrous intrinsèques vous permet d’avoir plusieurs conditions pour un verrou. Vous pouvez ainsi vous assurer que le thread notifié est en attente d’une condition particulière, ce qui évite le bogue de notification perdue dans le cas où un thread serait averti. quelque chose sur lequel il ne peut agir.)

Perspective simplifiée pour interpréter les vidages de threads:

  • ATTENDEZ- J'attends qu'on me donne du travail, alors je suis inactif en ce moment.
  • BLOQUÉ- Je suis occupé à essayer de travailler mais un autre fil se met en travers de mon chemin, alors je suis inactif pour le moment.
  • RUNNABLE... (Native Method) - J'ai appelé à exécuter un code natif (qui n'a pas encore fini) pour que vous puissiez exécuter RUNNABLE en ce qui concerne la machine virtuelle Java. tout complément d'information. Un exemple courant serait une méthode d’écoute de socket native codée en C qui attend en fait l’arrivée de tout le trafic. Je suis donc inactif pour le moment. Dans cette situation, cela peut être considéré comme un type spécial de WAIT car nous ne sommes pas du tout en train de courir (aucune gravure de processeur), mais vous devez utiliser un vidage de thread de système d'exploitation plutôt qu'un dump de thread Java pour le voir.
7
oldguy

Bloqué: votre thread est en état d'exécution du cycle de vie du thread et tente d'obtenir le verrouillage d'objet . Wait - Votre thread est en attente du cycle de vie du thread et attend le signal de notification pour qu'il soit en état d'exécution.

1
Prakash Bisht

voir cet exemple:

démonstration des états de fil.

/*NEW- thread object created, but not started.
RUNNABLE- thread is executing.
BLOCKED- waiting for monitor after calling wait() method.
WAITING- when wait() if called & waiting for notify() to be called.
  Also when join() is called.
TIMED_WAITING- when below methods are called:
 Thread.sleep
 Object.wait with timeout
 Thread.join with timeout
TERMINATED- thread returned from run() method.*/
public class ThreadBlockingState{

public static void main(String[] args) throws InterruptedException {
    Object obj= new Object();
    Object obj2 = new Object();
    Thread3 t3 = new Thread3(obj,obj2);
    Thread.sleep(1000);
    System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+
            ",when Wait() is called & waiting for notify() to be called.");
    Thread4 t4 = new Thread4(obj,obj2);
    Thread.sleep(3000);
    System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2.");
    System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called.");
}

}
class Thread3 extends Thread{
Object obj,obj2;
int cnt;
Thread3(Object obj,Object obj2){
    this.obj = obj;
    this.obj2 = obj2;
    this.start();
}

@Override
public void run() {
    super.run();
    synchronized (obj) {
        try {
            System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait().");
            obj.wait();             
            System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait().");
            synchronized (obj2) {
                cnt++;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}
class Thread4 extends Thread{
Object obj,obj2;
Thread4(Object obj,Object obj2){
    this.obj = obj;
    this.obj2 = obj2;
    this.start();
}

@Override
public void run() {
    super.run();
    synchronized (obj) {
        System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify().");
        obj.notify();
        System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify().");
    }
    synchronized (obj2) {
        try {
            Thread.sleep(15000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}
0
murali