最近有个需求, 当一个线程开始时, 需要实时判断这个线程是否存在, 去修改一些值.
场景:. 现在需要迁移一个公司的数据, 异步操作. 在系统中公司的数据如果在迁移, 不能重复迁移.
- // 发起迁移数据的进口, 这里因为这个操作不常用, 所以没有用线程池.
- // 原因是, 守护线程的限制. 线程池, 只是把线程放回线程池, 没有销毁, 所以守护线程无法判断到这个线程已经完成.
- // 如果要使用线程池, 可以在心跳守护线程中手动设置一个值控制
- Thread thread= new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- HeartbeatHelper.start(2, comId + "_" + module + "_trans");
- dataTansService.dataTransfer(comId, module, instance);
- } catch (Exception e) {
- LOGGER.error("迁移公司 [" + comId + "] 的数据失败, 原因:" + e.getMessage(), e);
- }
- }
- });
- thread.start();
- public class HeartbeatHelper {
- /**
- * 心跳缓存关键字前缀
- */
- private static final String ERP_HEARTBEAT_KEY_PREFIX = "HEARTBEAT_KEY_PREFIX_";
- private static CacheFacade cacheFacade = ApplicationContextManager.getBean(CacheFacade.class);
- /**
- * 启动心跳
- * @param key 关键字
- */
- public static void start(String key) {
- new HeartbeatDaemon(key).start();
- }
- /**
- * 判断心跳线程是否存在
- */
- public static boolean isLive(String key) {
- return PlatformUtils.hasText(cacheFacade.get(wrapKey(key)));
- }
- public static String wrapKey(String key) {
- return ERP_HEARTBEAT_KEY_PREFIX + key;
- }
- /**
- * 启动心跳
- * @param minute 心跳频率, 单位分钟
- * @param key 关键字
- */
- public static HeartbeatDaemon start(int minute, String key) {
- HeartbeatDaemon daemon = new HeartbeatDaemon(minute,key);
- daemon.start();
- return daemon;
- }
- public static class HeartbeatDaemon extends Thread {
- /**
- * 守护的对象: 即为创建该守护线程的线程对象
- */
- private final Thread guard;
- private static final String NAME_PREFIX = "guarding_";
- /**
- * 心跳频率为 10 分钟 1 次
- */
- private static final int HEART_RATE = 10;
- /**
- * 心跳频率, 单位分钟
- */
- private final int rate;
- /**
- * 缓存关键字
- */
- private final String key;
- private Logger logger = LoggerFactory.getLogger(HeartbeatHelper.class);
- public HeartbeatDaemon(int minute, String key) {
- this.rate = minute * CommonPlatformConstant.SECOND_MINUTE;
- this.key = key;
- setDaemon(true);
- guard = Thread.currentThread();
- setName(NAME_PREFIX + guard.getName());
- }
- public HeartbeatDaemon(String key) {
- this(HEART_RATE, key);
- }
- @Override
- public void run() {
- while (guard.isAlive()) {
- // 守护的线程活着的时候做的事情
- try {
- cacheFacade.set(wrapKey(key), DateUtils.formatDateTime(new Date()), rate);
- } catch (Exception e) {
- logger.error("更新心跳失败:" + e.getMessage(), e);
- }
- try {
- // 休眠时间应该小于键的有效时间
- Thread.sleep((rate -1) * CommonPlatformConstant.SECOND_OF_MILLISECOND);
- } catch (InterruptedException e) {
- logger.error("更新心跳休眠失败:" + e.getMessage(), e);
- }
- }
- }
- }
- }
来源: http://www.bubuko.com/infodetail-2993379.html