在线程中,notify--会唤醒一个等待线程、wait --会使当前线程进入等待状态,但是这两个方法都是属于Object类的,也就是对象调用。在我们平时使用时,大多直接使用this来替代当前对象,这样我们在理解时,我认为this代表的是当前线程对象,而一个线程对象对他的当前线程进行操作,是一个很正常的事,
看一个例子:
tes类有3个属性
public class Tes {
String A="a";
String B="b";
String C="c";
}
Mythread 类为线程类
public class Mythread implements Runnable{
private Object o1;
private Object o2;
private int i=100;
@Override
public void run() {
while(i>0){
synchronized (o1) {
synchronized (o2) {
System.out.println(i--+"-"+o1+"-"+Thread.currentThread().getName());
o2.notify();
}
try {
o1.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行,创建 3个线程对象,3个对象的成员都使用同一份资源,t
public static void main(String[] args) {
Tes t=new Tes();
Mythread m1=new Mythread(t.A,t.B);
Mythread m2=new Mythread(t.B,t.C);
Mythread m3=new Mythread(t.C,t.A);
Thread th1=new Thread(m1);
Thread th2=new Thread(m2);
Thread th3=new Thread(m3);
th1.start();
th2.start();
th3.start();
}
运行结果
a线程先进去会占用A,B两个资源,b、c两个线程会由于a线程的占用会暂时等待直到a线程释放锁,同时a线程进入等待状态直到b或者c线程唤醒a线程;
接下来将3条线程改为2条线程
public static void main(String[] args) {
Tes t=new Tes();
Mythread m1=new Mythread(t.A,t.B);
Mythread m2=new Mythread(t.B,t.C);
// Mythread m3=new Mythread(t.C,t.A);
Thread th1=new Thread(m1);
Thread th2=new Thread(m2);
// Thread th3=new Thread(m3);
th1.start();
th2.start();
// th3.start();
}
运行结果:
只有两个线程时会发现a,b线程都进入到等待状态,为什么a线程先进入等地状态,b线程无法唤醒它?
再来看wait, notify。wait会使当前线程进入等待,同时释放锁,notify会唤醒此对象的一条等待线程,a线程是由 A调用wait进入等待,那么也就应该由 A来唤醒,所以b线程中的唤醒是 C的线程,也就无法唤醒a线程,b线程也是因为没有B的notify调用,而无法唤醒。