超时等待
超时等待方法:Object.wait(remaining),remaining为等待时间
模型
等待持续时间:remaining
超时时间:future = System.currentTimeMills + remaining
伪代码:
public void waitMethod(long mills) {
long remaining = mills;
long future = System.currentTimeMillis + remaining;
synchronized(lock) {
// 条件循环判断,flag为线程共享变量,引入remaining判断退出循环
while (flag && remaining > 0) {
lock.wait(remaining);
remaining = future - System.currentTimeMillis;
}
......
}
}
例子
package com.waitnotify;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import com.waitnotify.WaitNotify.Notify;
import com.waitnotify.WaitNotify.Wait;
public class TimeWait {
static boolean flag = true;
static Object object = new Object();
public static void main(String[] args) throws InterruptedException {
Thread waitThread = new Thread(new Wait(), "WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(6);
Thread notifyThread = new Thread(new Notify(), "NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable {
@Override
public void run() {
synchronized (object) {
try {
long remaining = 5000; //超时等待5s
long future = System.currentTimeMillis() + remaining;
while (flag && remaining > 0) {
System.out.println(Thread.currentThread().getName() + " hold lock @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()) + ", flag is " + flag);
object.wait(remaining);
remaining = future - System.currentTimeMillis();
}
System.out.println(Thread.currentThread().getName() + " hold lock again @ "
+ new SimpleDateFormat("HH:mm:ss").format(new Date()) + ", flag is " + flag);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Notify implements Runnable {
@Override
public void run() {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() + " hold lock @"
+ new SimpleDateFormat("HH:mm:ss")
.format(new Date()));
object.notifyAll();
flag = false;
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() + " hold lock again @"
+ new SimpleDateFormat("HH:mm:ss")
.format(new Date()));
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}