ホームページ  >  記事  >  Java  >  Javaでスレッド待機と通知を実装する方法

Javaでスレッド待機と通知を実装する方法

黄舟
黄舟オリジナル
2017-09-26 10:06:531517ブラウズ

この記事では、Java でのスレッド待機と通知の実装に関する関連情報を主に紹介します。この記事が、このような機能を習得するのに役立つことを願っています。

Java でのスレッド待機と通知の実装

序文:

待機/通知に関して、覚えておくべき重要なポイントは次のとおりです:

wait()、notify()、およびnotifyAll() メソッドは、同期環境内から呼び出す必要があります。スレッドは、そのオブジェクトのロックを所有していない限り、オブジェクトの wait メソッドや notification メソッドを呼び出すことはできません。

wait()、notify()、notifyAll() はすべて Object のインスタンス メソッドです。各オブジェクトがロックを持つのと同じように、各オブジェクトは、そこからのシグナル (通知) を待つスレッドのリストを持つことができます。スレッドは、オブジェクトに対して wait() メソッドを実行することによって、この待機リストを取得します。その時点から、オブジェクトのnotify()メソッドが呼び出されるまで、他の命令は実行されません。複数のスレッドが同じオブジェクトを待機している場合、実行を継続するために 1 つのスレッドだけが (順序は保証されません) 選択されます。待機中のスレッドがない場合、特別なアクションは実行されません。

サンプルコード:


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());

  }

}

同期はクラスレベルの synchronized(A.class) またはオブジェクトレベルの synchronized(this) で行うことも、静的同期メソッドを使用することもできます。静的同期メソッドはクラス レベルであり、クラス オブジェクトはロックを取得した後にのみロックを実行できます。解放されます。 。

さらなるコード例は次のとおりです:


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();

  }

}

以上がJavaでスレッド待機と通知を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。