通信对象的等待集
- wait()
- 当前线程进入阻塞等待状态
- 当前线程释放它持有的锁
- 直到调用其他线程调用notify()方法或notifyAll()方法当前线程被唤醒进入就绪态
- notify()
随机唤醒任意一个当前对象上的阻塞等待线程
- notifyAll()
唤醒当前对象的所有阻塞等待线程
- wait(long timeout)
让当前线程处于“等待(阻塞)状态”,“直到其他线程调用此对象的notify()方法或 notifyAll() 方法,或者超过指定的时间量”,当前线程被唤醒(进入“就绪状态”),并且在wait()所在的代码处停止执行
wait()
- 当前线程进入阻塞等待状态,将当前线程置入“预执行队列”中,并且在wait()所在的代码处停止执行唤醒之后从当前停止处继续向下执行代码)
- wait()方法只能在同步方法或同步代码块中调用,没有持有适当的锁会抛出异常
- wait执行后当前线程释放锁,之后与其余线程重新竞争获取锁
notify()
- 在同步方法或同步块中调用
- 通知阻塞等待==该对象的的对象锁(notify()和wait()作用的对象要一样才起作用)==的其他线程,对其发出notify通知并使他们重新获得取该对象的对象锁。如果有多个线程等待,线程规划器随机挑选一个wait线程
- notify()方法执行完毕后,当前线程不会立刻释放对象锁,等notify()方法的线程执行完毕后,或者说是退出同步代码块或同步方法块之后才释放对象锁
public class Test8 {
public static void main(String[] args) throws InterruptedException {
Object obj=new Object();
myThread waitObj=new myThread(true,obj);
myThread notifyObj=new myThread(false,obj);
Thread t1=new Thread(waitObj);
Thread t2=new Thread(notifyObj);
t1.start();
Thread.sleep(1000);
t2.start();
System.out.println("main");
}
}
class myThread implements Runnable{
private boolean flag;
private Object obj;
public myThread(boolean flag, Object obj) {
this.flag = flag;
this.obj = obj;
}
@Override
public void run() {
if (flag){
synchronized (obj){
try {
System.out.println("等待中");
obj.wait();
System.out.println("等待结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else{
synchronized (obj){
System.out.println("等待唤醒");
obj.notify();
System.out.println("唤醒结束");
}
}
}
}
- notifyAll()
唤醒该对象对象锁的所有等待线程
package ThreadUse;
public class Test8 {
public static void main(String[] args) throws InterruptedException {
Object obj=new Object();
myThread waitObj1=new myThread(true,obj);
myThread waitObj2=new myThread(true,obj);
myThread waitObj3=new myThread(true,obj);
myThread notifyObj=new myThread(false,obj);
Thread t1=new Thread(waitObj1);
Thread t2=new Thread(waitObj2);
Thread t3=new Thread(waitObj3);
Thread t4=new Thread(notifyObj);
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
t4.start();
System.out.println("main");
}
}
class myThread implements Runnable{
private boolean flag;
private Object obj;
public myThread(boolean flag, Object obj) {
this.flag = flag;
this.obj = obj;
}
@Override
public void run() {
if (flag){
synchronized (obj){
try {
System.out.println("等待中");
obj.wait();
System.out.println("等待结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}else{
synchronized (obj){
System.out.println("等待唤醒");
obj.notifyAll();
System.out.println("唤醒结束");
}
}
}
}
- 注意
- wait,notify,notifyAll必须使用在synchronized同步方法或代码块
- notifyAll唤醒线程不能过早,如果在还没有线程在等待中时,过早的唤醒线程,这个时候就会出现先唤醒,在等待的效果了。这样 就没有必要在去运行wait方法了。