1.示例代码
package com.learning.protective_pause;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* @Author wangyouhui
* @Description 保护性暂停
**/
@Slf4j
public class GuardedObject {
// 结果
private Object response;
// 获取结果
public Object get(){
synchronized (this){
// 没有结果
while(response == null){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
return response;
}
}
// 产生结果
public void complete(Object response){
synchronized (this){
// 给结果成员变量赋值
this.response = response;
this.notifyAll();
}
}
public static void main(String[] args) {
GuardedObject guardedObject = new GuardedObject();
new Thread(()->{
// 等待结果
log.info("等待结果");
List<String> list = (List<String>)guardedObject.get();
log.info("list大小:{}",list.size());
}, "thread1").start();
new Thread(()->{
// 执行操作
List<String> list = new ArrayList();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add("1");
list.add("2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
guardedObject.complete(list);
}, "thread2").start();
}
}
2.带超时时间的示例代码
package com.learning.protective_pause;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.List;
/**
* @Author wangyouhui
* @Description 有等待时间的保护性暂停
**/
@Slf4j
public class GuardedObjectWithTime {
// 结果
private Object response;
// 获取结果
public Object get(long timeout){
synchronized (this){
// 记录一个开始时间
long beginTime = System.currentTimeMillis();
// 经过的时间
long usedTime = 0;
while(response == null){
// 这一轮循环应该等待的时间
long waitTime = timeout - usedTime;
// 经历的时间大于等于等待的时间,则跳出循环
if(waitTime <= 0){
break;
}
try{
// 如果是虚假唤醒,在等待时间内唤醒则继续执行,下一次wait则减去已经经历的时间
this.wait(timeout - usedTime);
}catch(InterruptedException e){
e.printStackTrace();
}
// 计算经历过的时间
usedTime = System.currentTimeMillis() - beginTime;
}
return response;
}
}
// 产生结果
public void complete(Object response){
synchronized (this){
// 给结果成员变量赋值
this.response = response;
this.notifyAll();
}
}
public static void main(String[] args) {
GuardedObjectWithTime guardedObject = new GuardedObjectWithTime();
new Thread(()->{
// 等待结果
log.info("等待结果");
List<String> list = (List<String>)guardedObject.get(500);
if(list != null){
log.info("list大小:{}",list.size());
}
log.info("end");
}, "thread1").start();
new Thread(()->{
// 执行操作
List<String> list = new ArrayList();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add("1");
list.add("2");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
guardedObject.complete(list);
}, "thread2").start();
}
}
3.join源码
public final synchronized void join(long millis) throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}