Maison  >  Article  >  Java  >  Comment implémenter l'attente de thread et la notification en Java

Comment implémenter l'attente de thread et la notification en Java

黄舟
黄舟original
2017-09-26 10:06:531518parcourir

Cet article présente principalement les informations pertinentes sur l'implémentation de l'attente des threads et des notifications en Java. J'espère que cet article pourra aider tout le monde à maîtriser ces fonctions. Les amis dans le besoin pourront s'y référer

Implémentation. de fil d'attente et de notification en java

Avant-propos :

Les points clés à retenir concernant l'attente/notification sont :

L'attente( ), notify() et notifyAll() doivent être appelées depuis l'environnement de synchronisation. Un thread ne peut pas appeler des méthodes d'attente ou de notification sur un objet à moins qu'il ne possède un verrou sur cet objet.

wait(), notify(), notifyAll() sont toutes des méthodes d'instance d'Object. Tout comme chaque objet possède un verrou, chaque objet peut avoir une liste de threads qui attendent des signaux (notifications) de sa part. Le thread obtient cette liste d'attente en exécutant la méthode wait() sur l'objet. À partir de ce moment, il n’exécute aucune autre instruction jusqu’à ce que la méthode notify() de l’objet soit appelée. Si plusieurs threads attendent sur le même objet, un seul thread sera sélectionné (sans ordre garanti) pour continuer l'exécution. Si aucun thread n'est en attente, aucune action spéciale n'est effectuée.

Exemple de code :


package threadwait;

public class ThreadA extends Thread{

  public int num = 0;

  public void run(){

    synchronized (this){//在此类对象上实现同步,this指代当前对象

      for(int i = 0 ; i < 3 ; ++i)

       this.num+=i;

      notifyAll();//通知所有在这个对象上等待的线程开始执行,在这里就是通知TestNotify主线程开始执行

    }

  }

  public int getNum(){

    return this.num;

  }

}


package threadwait;

 

public class TestNotify{

  public static void main(String args[]){

    ThreadA threada = new ThreadA();

    threada.start();//threada线程有执行的资格,但是还没有开始执行

    synchronized(threada){

      try{

       threada.wait();//主线程等待threada线程执行结束才开始执行

       //而且只有获得了当前threada对象的锁之后才能执行wait,就是说在同步域内才可以执行wait,执行wait后放弃对象锁

      }catch(InterruptedException e){

       e.printStackTrace();

      }

    }

    System.out.println(threada.getNum());

  }

}

La synchronisation peut être au niveau de la classe, synchronisée (A .class), il peut également être synchronisé(ce) au niveau de l'objet, qui peut être une méthode de synchronisation statique, synchronisée statiquement, la méthode de synchronisation statique est au niveau de la classe et la méthode de synchronisation non statique est au niveau de l'objet de classe niveau, a L'objet de classe n'a qu'un seul verrou. Ce n'est que lorsque le verrou est obtenu que l'opération d'attente peut être effectuée sur lui, puis le verrou est libéré.

Un autre exemple de code est le suivant :


package threadwait;

 

public class ThreadA extends Thread{

  public int num = 0;

  public void run(){

    synchronized (this){//在此类对象上实现同步,this指代当前对象

      for(int i = 0 ; i < 3 ; ++i)

       this.num+=i;

      try{

       Thread.sleep(500);//如果ThreadB的三个示例线程在还没有进入等待状态之前就受到了notifyall的信号

       //那将会发生严重后果,因为调用notifyall的线程只可以调用一次notifyall,那造成等待的线程将永远等待下去

       //所以在此处让它睡一小会,让其他线程有时间进入等待状态。

       //不然会收到

      }catch(InterruptedException e){

       e.printStackTrace();

      }

      notifyAll();//通知所有在这个对象上等待的线程开始执行,在这里就是通知TestNotify主线程开始执行

    }

//   notifyAll();

  }

  public int getNum(){

    return this.num;

  }

}


package threadwait;

 

public class ThreadB extends Thread{

  private ThreadA threada;

  public ThreadB(ThreadA ta){

    this.threada = ta;

  }

  public void run(){

    System.out.println(Thread.currentThread().getName()+" is waitting.");

    synchronized(threada){

      try{

       threada.wait();

      }catch(InterruptedException e){

       e.printStackTrace();

      }

      System.out.println(Thread.currentThread().getName()+" "+this.threada.getNum());

    }

   

  }

}


package threadwait;

 

public class TestNotify{

  public static void main(String args[]){

    ThreadA threada = new ThreadA();

    new ThreadB(threada).start();

    new ThreadB(threada).start();

    new ThreadB(threada).start();

    threada.start();

  }

}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn