1、需求
数据库中一条记录对应一个线程,线程会一直在跑。除非记录删除break。
需要满足,记录新增后自动启动新线程,编辑后,记录的线程判断条件更新。删除后结束。
2、构思
更新和删除可以在线程里面进行独立判断。
新增实现一:定时任务,根据线程名称来判断,名称有前缀+记录ID。如果线程活动,那么不新建,否则新建线程。
实现二:数据库mysql同步监听。
实现三:如果新增CRUD是自己平台所写。新增后发个通知即可。
结合实际情况及复杂度。选用方案一
深受阿里手册影响,一开始打算用ThreadPoolExecutor线程池来管理一批线程。但是ThreadFactory线程线程命名没法自定义,只能前缀+自增方式。
* 阿里巴巴手册不推荐直接使用 new Thread() 创建线程,而是推荐使用线程池来管理线程,主要有以下几个原因:
*
* 线程池可以复用线程,避免频繁创建和销毁线程,减少系统开销和资源消耗。
* 线程池可以控制线程的并发数,避免过多的线程导致系统资源耗尽,提高系统的稳定性和可靠性。
* 线程池可以提供更好的线程调度和管理能力,比如可以设置线程的优先级、超时时间等,以满足不同的业务需求。
* 线程池可以更好地支持异步操作和回调机制,提高系统的响应速度和可扩展性。
结合项目情况,不存在频繁创建于销毁。后来还是决定显示创建线程。可自定义名称。
3、实现
/**
* @author cmy
* @date 2023/9/6 13:56
*/
@Configuration
@EnableScheduling
@Slf4j
public class Test {
private static final String THREAD_PREFIX = "MONITOR-";
@Resource
ExceptionFaultMonitorService exceptionFaultMonitorService;
@Scheduled(fixedRate = 60 * 1000)
private void configureTasks() {
log.info(System.currentTimeMillis()+"定时任务开启");
List<ExceptionFaultMonitor> list = this.exceptionFaultMonitorService.list();
if(list.isEmpty()){
return;
}
System.out.println(list.size());
List<String> monitorThread = new ArrayList<>(list.size());
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] lstThreads = new Thread[noThreads];
currentGroup.enumerate(lstThreads);
System.out.println("现有线程个数:" + noThreads);
// 遍历线程
for (int i = 0; i < noThreads; i++) {
String threadName = lstThreads[i].getName();
System.out.println("ALL threadName = " + threadName);
if(threadName.startsWith(THREAD_PREFIX)){
monitorThread.add(threadName);
}
}
for (ExceptionFaultMonitor bean : list) {
String threadName = THREAD_PREFIX+bean.getId();
if(monitorThread.contains(threadName)){
System.out.println(threadName + "已运行");
}else{
TestRunnable testRunnable = new TestRunnable();
Thread thread = new Thread(testRunnable,threadName);
thread.start();
}
}
log.info(System.currentTimeMillis()+"定时任务结束");
}
}
后期新建线程的时候,也可指定线程分组。
每60S去读库