多线程的等待唤醒机制:
举例转载:
小时候,我们都起一玩过一个游戏,名字想不起来了,就是一伙小朋 友,抽出其中最走运的一个,其他的就到处跑,逃离最走运的,规矩:当最走运的小盆友要住抓其他小盆友中的一个时,如果反响的快时,说一声“木(定,就是不能动)”,走运的小盆友就不能抓他,而去抓其他的,只有等到其他的小盆友来碰他(木的那个)一下,才可以被拯救,又当部全木完时,最走运的小盆友就变运幸了,同时部全拯救。
析分:最走运的小盆友就如CPU,做着切换动作, 其中木的那个小盆友就如一个线程,“木”就如wait(),碰他一下就如notify(),部全拯救就如notifyAll(),
线程之间的关系是同等的,彼此之间不并存在任何依附,它们各自竞争CPU资源,各执己见,并且还无条件地阻挠其他线程对共享资源的步异问访。然而,也有很多现实问题求要不仅要步同的问访统一共享资源,而且线程间还彼此制牵,通过互相通信来向前进推。
等待唤醒机制所涉及到的方法:
package util;
wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。
notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。
notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。
public class Resource {
public static Resource r = null;
String name;
String sex;
boolean flag = false;
public static Resource getResource(){
if(r == null){
synchronized (Resource.class) {
if(r == null){
r = new Resource();
}
}
}
return r;
}
}
package util;
public class Input implements Runnable{
private Resource r;
public Input(Resource r){
this.r = r;
}
public void run() {
int x = 0;
while(true){
synchronized (r) {
if(r.flag){
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(x == 0){
r.name = "mike";
r.sex = "man";
}else{
r.name = "林心如";
r.sex = "女";
}
x = (x+1)%2;
r.flag = true;
r.notifyAll();
}
}
}
}
package util;
public class Output implements Runnable{
private Resource r;
public Output(Resource r){
this.r = r;
}
public void run() {
while(true){
synchronized (r) {
if(!r.flag){
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(r.name+"-----"+r.sex);
r.flag = false;
r.notifyAll();
}
}
}
}
package util;
public class InputOuputDemo {
public static void main(String[] args) {
Input i = new Input(Resource.getResource());
Output o = new Output(Resource.getResource());
Thread t1 = new Thread(i);
Thread t2 = new Thread(o);
t1.start();
t2.start();
}
}