若有雷同,请联系本人删除
wait();
notify();
notifyAll();
本文中的每句话都要好好理解,都有比较深刻的意义。
这三个方法都是Object的三个方法。
synchronized(x){
}
wait()方法,释放对象锁,让该线程等待。直到被notify或者被notifyAll
最后结论就是:被wait的线程,想要继续运行的话,它必须满足2个条件:
- 由其他线程notify或notifyAll了,并且当前线程被通知到了
- 经过和其他线程进行锁竞争,成功获取到锁了
Thread.sleep(long l);方法,不释放对象锁,让该线程睡眠l时间(单位是毫秒),过了睡眠时间,重新回到可执行状态
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于:
notifyAll使在该对象上所有wait状态的线程变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。
notify则文明得多,他只是选择一个wait状态线程进行通知,并使它变成等待该对象上的锁,一旦该对象被解锁,它自己去执行。
即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象再次发出一个notify或notifyAll。
来来来,上例子:
package com.wyl.wait;
public class WaitTest1 implements Runnable{
public int i5=0;
public WaitTest1(int i5){
this.i5=i5;
}
@Override
public synchronized void run() {
i5=i5-1;
if(i5>=2){
System.out.println("wait方法研究2"+Thread.currentThread().getState());
try {
Thread.sleep(8000);
System.out.println("I'am over"+Thread.currentThread().getState());
wait();
System.out.println("我被解锁了"+Thread.currentThread().getState());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println("我来了兄弟们"+Thread.currentThread().getState());
notifyAll();
}
}
/**
* 运行流程如下:
* 1,新建线程tr,并start,打印 "刚创建1RUNNABLE"
* 2,tr新建完成后,发现run方法可用,cpu资源可用,那么马上进入。打印"wait方法研究2RUNNABLE",后来线程进入睡眠3s,这时候,主进程main方法要继续
* 3,新建线程tr2,并start
* 4,tr2打印"刚创建2RUNNABLE"
* 5,tr2调用start后,并不能立即执行,因为要等待tr的sleep()结束,因为此时方法被锁定,tr2并不能进入
* 6,过了8s,tr2进入了run方法,因为sleep()结束,目前tr在wait.直到他被notify或者notifyAll。此时tr释放了同步锁资源,允许tr2进来,
* 打印"我来了兄弟们RUNNABLE".唤醒了所有wait的线程
* 7,这时候tr从wait被唤醒了。所以继续执行,打印"我被解锁了RUNNABLE"
*/
public static void main(String[] args){
WaitTest1 wt=new WaitTest1(3);
Thread tr=new Thread(wt);
tr.start();
System.out.println("刚创建1"+Thread.currentThread().getState());
Thread tr2=new Thread(wt);
tr2.start();
System.out.println("刚创建2"+Thread.currentThread().getState());
}
}
好好理解吧,骚年们。
欢迎加我微信交流技术。