Java中使用wait()与notify()实现线程间协作

使用wait()与notify()/notifyAll()可以使得多个任务之间彼 此协作。

1. wait()与notify()/notifyAll()

调用sleep()和yield()的时候锁并没有被释放,而调用wait() 将释放锁。这样另一个任务(线程)可以获得当前对象的锁,从而 进入它的synchronized方法中。可以通过notify()/notifyAll(), 或者时间到期,从wait()中恢复执行。

只能在同步控制方法或同步块中调用wait()、notify()和 notifyAll()。如果在非同步的方法里调用这些方法,在运行时会 抛出IllegalMoniTorStateException异常。

2.模拟单个线程对多个线程的唤醒

模拟线程之间的协作。Game类有2个同步方法prepare()和go() 。标志位start用于判断当前线程是否需要wait()。Game类的实例 首先启动所有的Athele类实例,使其进入wait()状态,在一段时间 后,改变标志位并notifyAll()所有处于wait状态的Athele线程。

Game.java

package concurrency;import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.IteraTor;import java.util.Set;class Athlete implements Runnable {   private final int id;   private Game game;   public Athlete(int id, Game game) {    this.id = id;    this.game = game;   }   public boolean equals(Object o) {    if (!(o instanceof Athlete))     return false;    Athlete athlete = (Athlete) o;    return id == athlete.id;   }   public String toString() {    return "Athlete";   }   public int hashCode() {    return new Integer(id).hashCode();   }   public void run() {    try {     game.prepare(this);    } catch (InterruptedException e) {     System.out.println(this + " quit the game");    }   }  }public class Game implements Runnable {   private Set players = new HashSet();   private boolean start = false;   public void addPlayer(Athlete one) {    players.add(one);   }   public void removePlayer(Athlete one) {    players.remove(one);   }   public Collection getPlayers() {    return Collections.unmodifiableSet(players);   }   public void prepare(Athlete athlete) throws InterruptedException {    System.out.println(athlete + " ready!");    synchronized (this) {     while (!start)     wait();     if (start)       System.out.println(athlete + " go!");    }   }   public synchronized void go() {    notifyAll();   }   public void ready() {    IteraTor iter = getPlayers ().iteraTor();    while (iter.hasNext())     new Thread(iter.next()).start();   }   public void run() {    start = false;    System.out.println("Ready......");    System.out.println("Ready......");    System.out.println("Ready......");    ready();    start = true;    System.out.println("Go!");    go();   }   public static void main(String[] args) {    Game game = new Game();    for (int i = 0; i < 10; i++)     game.addPlayer(new Athlete(i, game));    new Thread(game).start();   }}

结果:

Ready......Ready......Ready......Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Athlete ready!Go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!Athlete go!

3.模拟忙等待过程

MyObject类的实例是被观察者,当观察事件发生时,它会通知 一个MoniTor类的实例(通知的方式是改变一个标志位)。而此 MoniTor类的实例是通过忙等待来不断的检查标志位是否变化。

BusyWaiting.java

<p “但行好事,莫问前程”,往往成功的几率反而更大些;

Java中使用wait()与notify()实现线程间协作

相关文章:

你感兴趣的文章:

标签云: