最近我们的伟哥讲了一个多线程的唤醒机制,刚开始,很是不懂,不过经过一个中午的思考,终于弄明白了,现在分享给大家。
代码是这样的:
线程t1: synchronized (s) {
//如果有数据,就等待。
if(s.flag){
try {
s.wait();//t1等待了,
} catch (InterruptedException e) {
e.printStackTrace();
}
}
s.name = "林青霞"; // t2抢到;
s.age = 26;
//修改标记
s.flag = true;
s.notify();//唤醒了t2,这个时候,可能是t1继续,或者t2抢到。
}
线程t2:synchronized (s) {
if(!s.flag){
try {
s.wait();//t2等待了。wait()的线程,被唤醒后,继续执行。wait()方法出现后,对应的线程就释放了锁对象
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "***" + s.age);
//修改标记
s.flag = false;
s.notify(); //t1被唤醒,但是不一定会立马执行。
}
注:其中的flag为布尔型变量
我自己的理解::lol
t1线程:
if(flag){
t1执行功能方法并改flag值,同时唤醒t2线程
else{
t1变为等待状态
}
t2线程:
if(!flag){
t2执行功能方法并改flag值,同时唤醒t1线程
}
else{
t2变为等待状态
}
后来再经过我考虑,我发现,这个过程其实多了一步,因为如果先执行了t1这个线程并flag为true,那么先执行t1的功能方法,再唤醒t2。注意!此时如果又被t1线程抢到,这时t1线程才变为等待状态。为什么不在执行完t1的功能方法后,直接把t1线程关掉,这样不就省下了一步吗?
即这样:(这个没有布尔型变量)
t1线程:{执行t1功能方法 并让t1等待 同时唤醒t2}。这个是一次性做完,下个也是。
t2线程:{执行t2功能方法 并让t2等待 同时唤醒t1}。
不过当我查了API我才明白: 唤醒线程这个功能并没有明确指定会唤醒哪个线程。 所以如果t2先执行,t1再执行到把t1线程也成为等待状态的时候。注意!此时,两个线程都处于等待状态,所以此时再执行唤醒线程功能,它会懵。很有可能会又唤醒t1线程,然后t1线程再变为等待,然后再唤醒t1线程。。。。:funk:
这次的体验真的爽到了。(由于还要着急复习,所以很有可能我会写错什么,欢迎批评和指正)。
明天就是我们0416班点招了,希望我们都过,保佑我们都过:lol加油!!!!!!!0416!!
|