目录
前言
工作中的场景中是否存在类似这样的场景,需要提交的线程在某个触发条件下执行。本文主要就是使用guava中的monitor来优雅的实现带监视器的线程。
Maven依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
代码
不废话上代码。
package com.huyi.csdn.tools;
import cn.hutool.core.thread.ThreadUtil;
import com.google.common.util.concurrent.Monitor;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
/**
* @Program: csdn @ClassName: MonitorRunner @Author: huyi @Date: 2021-10-30 15:22 @Description:
* 监视器Runner @Version: V1.0
*/
public class MonitorRunner<T> implements Runnable {
private T param;
private Function<T, Boolean> condition;
private Runnable runnable;
private Monitor monitor;
/**
* 构造函数
*
* @param param 判断参数
* @param condition 判定函数
* @param runnable 执行内容
*/
public MonitorRunner(T param, Function<T, Boolean> condition, Runnable runnable) {
this.param = param;
this.condition = condition;
this.runnable = runnable;
monitor = new Monitor();
}
@Override
public void run() {
System.out.println("线程开始");
Monitor.Guard guard =
new Monitor.Guard(monitor) {
@Override
public boolean isSatisfied() {
return condition.apply(param);
}
};
while (true) {
if (monitor.enterIf(guard)) {
try {
runnable.run();
} finally {
monitor.leave();
break;
}
} else {
continue;
}
}
}
public T getParam() {
return param;
}
public MonitorRunner<T> setParam(T param) {
this.param = param;
return this;
}
public static void main(String[] args) {
ExecutorService executorService =
Executors.newFixedThreadPool(10, new CustomizableThreadFactory("MONITOR-"));
MonitorRunner<Integer> monitorRunner =
new MonitorRunner<>(
0,
x -> x > 10,
() -> {
// todo 线程需要执行的内容
System.out.println("今天天气真好");
});
executorService.submit(monitorRunner);
while (monitorRunner.getParam() <= 10) {
monitorRunner.setParam(monitorRunner.getParam() + 1);
ThreadUtil.sleep(1000L);
System.out.println("当前Param的值:" + monitorRunner.getParam());
}
ThreadUtil.sleep(5000L);
executorService.shutdown();
}
}
代码说明
主要在构造对象的时候需要传递泛型的校验对象,以及断言和需要执行的Runable。
执行结果
总结
没啥好总结的,看场景使用吧。
如果本文对你有用,请点个赞吧,谢谢。