假设线程1执行了wait(),线程2获取到了锁资源,与此同时线程3启动执行synchronized竞争锁资源,线程2在结束之前使用了notifyAll()唤醒线程1,那么线程1和线程3谁能获取到锁是随机的吗?
在我的理解中,是随机的,但是现在的实际情况是线程1会获取到资源
请问是我理解错了吗,请说明一下。
还有就是线程1执行了wait之后,线程4先获取到锁资源,但是也执行了wait,然后按照上面的继续进行下去的,在线程2结束的时候,为什么会执行线程1和线程4。
public class ThreadTest {
public static void main(String[] args) {
Object co = new Object();
System.out.println(co);
for (int i = 0; i < 10; i++) {
MyThread t = new MyThread("Thread" + i, co);
t.start();
}
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("-----Main Thread notify-----");
synchronized (co) {
co.notify();
}
TimeUnit.SECONDS.sleep(2);
System.out.println("Main Thread is end.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class MyThread extends Thread {
private String name;
private Object co;
public MyThread(String name, Object o) {
this.name = name;
this.co = o;
}
@Override
public void run() {
System.out.println(name + " is waiting.");
try {
synchronized (co) {
co.wait();
}
System.out.println(name + " has been notified.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
比如说这个代码,先不管他会造成死锁,问题是main中那个notify释放的,一定会是第一个执行wait的,难道不是随机的吗??
这个我测试了一下
把你co.notify()改成notifyAll(),结果每次都是Thread-0被首先唤醒,然后其他是随机的。
目前我只能认为是编译器的优化。
想达到随机唤醒,来 一睡解千愁
@Override
public void run() {
System.out.println(name + " is waiting. theThreadName :"+Thread.currentThread().getName());
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
synchronized (co) {
co.wait();
}
System.out.println(name + " has been notified theThreadName :"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
这个要看cpu分配了,也要看线程的优先级
理论上来说是cpu随机分配的,但是线程本身可以设置优先级,但优先级也只是更改概率罢了
按照Think in Java中的解释:"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."
先wait的线程优先