wait()和notify()方法属于Object类中的方法,是用于对线程之间进行资源对象锁的通信,其必须在synchronized(Obj){...}语法块内
wait()就是说线程在获取对象锁后,主动释放对象锁,同时本线程进行休眠。直到有其它线程调用该对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行
notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行
eg1.一个很经典的面试题,用线程锁实现打印机打印ABCABCABCABCABC
package com.lmr.thread;
//线程加锁
public class TestSynchronized {
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Object b = new Object();
Object c = new Object();
Thread thread1=new Thread(new MyThreadPrint("A",c,a));
Thread thread2=new Thread(new MyThreadPrint("B",a,b));
Thread thread3=new Thread(new MyThreadPrint("C",b,c));
thread1.start();
Thread.sleep(100);
thread2.start();
Thread.sleep(100);
thread3.start();
Thread.sleep(100);
}
}
class MyThreadPrint implements Runnable{
private String name;
private Object prev;
private Object self;
public MyThreadPrint(String name, Object prev, Object self){
this.name=name;
this.prev=prev;
this.self=self;
}
@Override
public void run() {
// TODO Auto-generated method stub
int count=5;
while(count>0){
synchronized (prev) {
synchronized (self) {
System.out.println(" "+count+" "+name);
count--;
self.notify();
}
try {
prev.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
5 A
5 B
5 C
4 A
4 B
4 C
3 A
3 B
3 C
2 A
2 B
2 C
1 A
1 B
1 C
eg2.利用wait()和notify()实现线程的暂停和继续
package com.lmr.thread;
public class Runnable_1 extends Thread implements Runnable{
private int num=0;
private Boolean flag = false;
private Object lock=new Object();
public Boolean getFlag() {
return flag;
}
public void setFlag(Boolean flag) {
if(flag){
synchronized (lock) {
lock.notify();
}
}
this.flag = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
synchronized (lock) {
if(!flag){
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(num++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
对应的使用方式
thread1=new Runnable_1();
thread1.start();
thread1.setFlag(true);//将线程继续
thread1.setFlag(false);//将线程暂停