当需要多个线程共同完成一个任务时,需要它们有规律的执行,多个线程之间需要一些通信的机制,以实现共同操作一份数据。
说是通讯机制,并不是让线程之间会交流讲话,而是用几个方法来控制线程直线通断的顺序。
例如:线程a生产包子,线程b负责吃包子。b线程就需要等a线程执行完毕才可以执行。
使用notify和wait方法交替唤醒和阻塞的状态
public class PrintChange {
public static void main(String[] args) {
PrintNumber1 pp1=new PrintNumber1();
Thread tt1=new Thread(pp1);
Thread tt2=new Thread(pp1);
tt1.start();
tt2.start();
}
}
class PrintNumber1 implements Runnable{
private int number=1;
@Override
public void run() {
while(true){
synchronized(this) {
if(number<100){
//唤醒线程
notify();
try {
//sleep不会释放同步监视器
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+number);
number+=1;
try {
//当前线程打印完阻塞一下,同时释放同步监视器的调用
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}
}
}
}
}
方法名 | 作用 |
---|---|
notify() | 一旦执行此方法,就会唤醒被wait()的优先级最高的一个线程,如果优先级相同则随机唤醒一个,唤醒的线程从当初被wait()的位置继续执行 |
notifyAll() | 唤醒全部被wait()的线程 |
wait() | 一旦执行此方法就会进入等待状态,同时释放同步监视器的调用 |
注意:
此三个方法只能使用在同步代码块synchronized或同步方法中
此方法的调用者,就是同步监视器
wait | sleep |
---|---|
一旦执行则进入阻塞状态 | 一旦执行则进入阻塞状态 |
声明在Object中 | 声明在Thread中 |
只能使用在同步代码块或同步方法中 | 任意位置 |
一单执行会释放同步监视器 | 执行时不会释放同步监视器 |
到达指定时间自动结束阻塞,或被notify唤醒 | 到达指定时间自动结束阻塞 |
推荐阅读: