package com.hivekion.room.bean; import com.hivekion.common.uuid.IdUtils; import com.hivekion.room.func.TaskAction; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import lombok.Data; /** * [类的简要说明] *

* [详细描述,可选] *

* * @author LiDongYU * @since 2025/7/22 */ @Data public class Room implements AutoCloseable { private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); private ScheduledFuture future; private String roomId; private Map> actionMap = new ConcurrentHashMap<>(); //线程池 private final ExecutorService actionExecutor = new ThreadPoolExecutor( 5, 5, // corePoolSize, maximumPoolSize 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1000), // 有界队列,只允许100个待执行任务 new ThreadPoolExecutor.AbortPolicy() // 超出直接抛异常 ); public Room(String roomId) { this.roomId = roomId; } /** * 剩余时间 */ private AtomicLong duringTime = new AtomicLong(0); private AtomicLong totalTime = new AtomicLong(0); private int mag = 1; //获取剩余时间 public long getDuringTime() { return duringTime.get(); } /** * 启动 * * @param time 总时间 */ public void start(long time) { totalTime.set(time); startTask(); } /** * 停止 */ public void stop() { cancelTask(); } /** * 暂停 */ public void pause() { cancelTask(); } public void resume() { startTask(); } /** * 快进 * * @param mag 放大倍数 */ public void magChange(int mag) { this.mag = mag; } // 启动定时任务 private void startTask() { if (future == null || future.isCancelled()) { future = scheduler.scheduleAtFixedRate(() -> { long curTime = duringTime.addAndGet(this.mag); // 推荐用 addAndGet Map actions = actionMap.get(curTime); if (actions != null && !actions.isEmpty()) { // 先复制key,避免并发删除问题 for (Map.Entry entry : actions.entrySet()) { actionExecutor.submit(entry.getValue()::doSomeThing); } // 全部执行后再清空 actions.clear(); // 或者 actionMap.remove(curTime); 如果你不需要重用这个 key actionMap.remove(curTime); } }, 0, 1, TimeUnit.SECONDS); } } // 取消定时任务 private void cancelTask() { if (future != null && !future.isCancelled()) { future.cancel(true); } } public void addAction(long time, TaskAction action) { actionMap.computeIfAbsent(time, k -> new ConcurrentHashMap<>()) .put(IdUtils.simpleUUID(), action); } @Override public void close() throws Exception { actionMap.clear(); if (future != null && !future.isCancelled()) { future.cancel(true); } if (scheduler != null && !scheduler.isShutdown()) { scheduler.shutdown(); } } }