这篇来学习Object类下两个方法,分别是wait()和notify(), 这两个方法是在多线程中设置线程等待和唤醒线程的作用。这篇,通过两个线程的例子来学习wait()线程等待方法和notify()唤醒线程方法。
1.两个线程,打印两句话。
前面文章,有类似下面的代码,两个线程随机打印两句话。
package thread;
public class Notify_Demo {
public static void main(String[] args) {
printer p = new printer();
new Thread() {
public void run() {
while(true) {
p.printer1();
}
}
}.start();
new Thread() {
public void run() {
while(true) {
p.printer2();
}
}
}.start();
}
}
class printer {
public void printer1() {
System.out.print("跟");
System.out.print("我");
System.out.print("一");
System.out.print("起");
System.out.println("念");
}
public void printer2() {
synchronized (printer.class) {
System.out.print("做");
System.out.print("测");
System.out.print("试");
System.out.print("死");
System.out.print("路");
System.out.print("一");
System.out.println("条");
}
}
}
这个运行的效果是,先随机打印N个重复的“跟我一起念”,然后随机重复打印N个“做测试死路一条”。
那么,如果我们现在需要,先打印一遍“跟我一起念”,然后里面跟着打印一遍“做测试死路一条”。这个要怎么做呢?这个时候就要用到Object类下的wait()和notify()方法。
大概代码实现的场景是这样的,线程A先打印“跟我一起念”一遍,线程A进入等待,这个时候需要用wait()方法,然后线程B启动区打印“做测试死路一条”,为什么会启动呢,这里就需要用到notify()唤醒线程的功能,然后线程B等待,唤醒线程A,这样循环下去。
实现代码如下
package thread;
public class Notify_Demo {
public static void main(String[] args) {
printer p = new printer();
new Thread() {
public void run() {
while(true) {
try {
p.printer1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
try {
p.printer2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
class printer {
private int flag = 1;
public void printer1() throws InterruptedException {
synchronized (this) {
if(flag != 1) {
this.wait(); // 设置线程等待,如果flag 不等于1
}
System.out.print("跟");
System.out.print("我");
System.out.print("一");
System.out.print("起");
System.out.println("念");
flag = 2;
this.notify(); // 设置flag等于2,使用线程唤醒功能,其他线程就可以启动
}
}
public void printer2() throws InterruptedException {
synchronized (this) {
if(flag != 2) {
this.wait(); // 设置线程等待,如果flag 不等于2
}
System.out.print("做");
System.out.print("测");
System.out.print("试");
System.out.print("死");
System.out.print("路");
System.out.print("一");
System.out.println("条");
flag = 1;
this.notify(); //随机唤醒单个等待的线程
}
}
}
运行效果
跟我一起念
做测试死路一条
跟我一起念
做测试死路一条
跟我一起念
做测试死路一条
跟我一起念
做测试死路一条
...
上面就是两个线程之间的通信过程,线程A执行,线程B等待,线程B等待唤醒线程A,这样循环。