所谓线程的交互就是程序里唯一的synchronized是如何在多线程之间进行传递的。
在交互中主要用到的方法:
Public void wait() :导致当前的正在运行的线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll() 方法。
Public void wait(long timeout) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
public void wait(long timeout, int nanos) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
void notify() :唤醒在此对象监视器上等待的单个线程。
void notifyAll():唤醒在此对象监视器上等待的所有线程。
注意:
1.线程不能调用对象上等待或通知的方法,除非它拥有那个对象的锁。
2.Wait(),notify(),notifyAll()在同步环境变量中调用。
3.XX.wait(),XX.notify(),XX.notifyAll()中的XX指的是监视器而不是对象。Wait停止进行的是其所者的主线程。
下面是一段两线程交互的代码:
public class ThreadA {
public static void main(String[] args) {
ThreadB b = new ThreadB();
//启动计算线程
b.start();
//线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者
synchronized (b) {
try {
System.out.println("等待对象b完成计算。。。");
//当前线程A等待
b.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("b对象计算的总和是:" + b.total);
}
}
}
/**
* 计算1+2+3 ... +100的和
*/
public class ThreadB extends Thread {
int total;
public void run() {
synchronized (this) {
for (int i = 0; i < 101; i++) {
total += i;
}
//(完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒
notify();
}
}
}
注意:当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程仍然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁变得可用。