demo:
为方便展示,这里有两个类 : Tasker 、Customer
在Customer中,其构造器需要传入Tasker对象,这样我们才能在后面的代码中捕获当前tasker对象,并唤醒该对象等待的线程。
public class Tasker implements Runnable{ public void doSth() throws InterruptedException{ synchronized (this) { for (int i = 0; i < 10; i++) { if(i==5){ this.wait(); } System.out.println("i = " + i); } } } public void wake(){ //唤醒对象 System.out.println("start to wake up"); this.notifyAll(); System.out.println("wake up finished"); } @Override public void run() { //获取对象唤醒对象 synchronized(this){ this.wake(); } } public static void main(String[] args) throws InterruptedException { Tasker t = new Tasker(); Customer cust = new Customer(t); new Thread(cust).start(); Thread.sleep(3000); new Thread(t).start(); } }
public class Customer implements Runnable { private Tasker tasker; public Customer(Tasker tasker){ this.tasker = tasker; } public void doSth() throws InterruptedException{ tasker.doSth(); } @Override public void run() { try { doSth(); } catch (InterruptedException e) { e.printStackTrace(); } } }
从main方法解读:
声明一个tasker对象并交给声明的customer,customer启动线程,调用当前tasker的doSth方法。该方法线程在执行到某条件处wait()。另一方面,当前对象tasker自己也启动线程,调用自己的wake方法。wake方法唤醒了该对象的所有等待线程。doSth方法执行完毕! jdk中要求,唤醒其他线程的代码需写在 同步方法或同步块中。