实例:两个线程轮流执行
package com.heima.day25;
public class Demo004 {
public static void main(String[] args) {
Print print = new Print();
new Thread(){
public void run() {
for(int i=1;i<=100;i++){
try {
print.print1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
new Thread(){
public void run() {
for(int i=1;i<=100;i++){
try {
print.print2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
}
}
class Print{
private int flag = 1;
/*
* 锁对象 为obj
* 如果调用wait()和notify()方法的不是锁对象,那么会报错
* java.lang.IllegalMonitorStateException
* obj.wait() 和 obj.notify() 必须要在synchronized内调用否则报错
* java.lang.IllegalMonitorStateException
*/
Object obj = new Object();
public void print1() throws InterruptedException{
synchronized (obj) {
if(flag!=1){
obj.wait();
}
System.out.print("黑");
System.out.print("马");
System.out.print("程");
System.out.print("序");
System.out.print("员");
System.out.print("\r\n");
flag = 2;
obj.notify();
System.out.println(Thread.currentThread().getName());
}
}
public void print2() throws InterruptedException{
synchronized (obj) {
if(flag != 2){
obj.wait();
}
System.out.print("传");
System.out.print("智");
System.out.print("播");
System.out.print("客");
System.out.print("\r\n");
flag = 1;
obj.notify();
System.out.println(Thread.currentThread().getName());
}
}
}
wait():导致当前线程等待并使其进入到等待阻塞状态。直到其他线程调用该同步锁对象的notify()或notifyAll()方法来唤醒此线程。
notify():唤醒在此同步锁对象上等待的单个线程,如果有多个线程都在此同步锁对象上等待,则会任意选择其中某个线程进行唤醒操作,只有当前线程放弃对同步锁对象的锁定,才可能执行被唤醒的线程。
注:wait() 和 notify()必须由锁对象来执行,否则会报错:java.lang.IllegalMonitorStateException。
一些资料:
《java编程思想》第四版一书中有描述到:“线程操作的wait()、notify()、notifyAll()方法只能在同步控制方法或同步控制块内调用。如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 IllegalMonitorStateException 异常,并伴随着一些含糊信息,比如 ‘当前线程不是拥有者’。其实异常的含义是 调用wait()、notify()、notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。”