描述:
1、调用该方法,导致当前线程(用T表示)阻塞,进入等待状态。
当前线程T会把自己放入 等待集合 中(等待 obj.wait()的obj对象)。
2、当前线程(T)程释放已获取obj的锁(别的线程可以获取了,如果有)。
3、什么时候唤醒(从wait set 删除)?以下4种事件任何一个发生,即会唤醒。
a, 其它的线程调用 obj.notify(),且当前线程T,正好是被选中唤醒的。
b, 其它的线程调用 obj.notifyAll()。
c.其它线程中断T。
d.指定的等待时间(timeout)超时,(时间精度会有些误差)。
4、当前线程T被唤醒后,它被移出等待集合,重新被调度。
它需要和其它线程平等的(没有任何特权)竞争,获取obj的锁。
本文标题,永远不会唤醒,其实不是不会唤醒,而是唤醒后,可能获取不到锁。
代码示例:
package com.wateray.java.thread;
public class WaitTimeDemo {
/**
* @param args
*/
public static void main(String[] args) {
Object obj = new Object();
Thread thA = new Thread(new Task2(obj));
thA.setName("thread A");
thA.start();
// thB run forever!
Thread thB = new Thread(new Task3(obj));
thB.setName("thread B");
thB.start();
}
}
class Task2 implements Runnable {
private Object obj;
public Task2(Object obj) {
this.obj = obj;
}
@Override
public void run() {
while (true) {
synchronized (obj) {
try {
System.out.format("%s waiting...%n%n", Thread
.currentThread().getName());
// 等待1秒,wait会释放锁
obj.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.format("%s awaked!%n%n", Thread.currentThread()
.getName());
}
}
}
class Task3 implements Runnable {
private Object obj;
public Task3(Object obj) {
this.obj = obj;
}
@Override
public void run() {
long start = System.currentTimeMillis();
synchronized (obj) {
// 获取锁后,永不释放
while (true) {
try {
// 每5秒打印一次
if ((System.currentTimeMillis() - start) % 5000 == 0) {
System.out.format("%s ...%n%n", Thread.currentThread()
.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}