Java中怎么实现双保险线程
创始人
2024-12-24 16:42:43
0次

双保险线程,每次启动2个相同的线程,互相检测,避免线程死锁造成影响。

两个线程都运行,但只有一个线程执行业务,但都会检测对方的时间戳 如果时间戳超过休眠时间3倍没有更新的话,则重新启动对方线程。

例子:

一般工作线程由自己实现,继承DoubleInsuredThead,在run2()方法里实现具体需求,和一般线程的run()方法不同,run2()里不用处理循环和休眠 检测线程已经由CheckThread实现,可以直接使用,如:启动用户检测线程。

public static void startMonitor() { System.out.println("启动用户会话检测线程"); UserMonitor worker = new UserMonitor("WT-UserMonitor"); CheckThread checker = new CheckThread("WT-UserMonitorCheck",userMonitorIntevalTime); DoubleInsuredThead.startDoubleInsuredThead(worker, checker);}

完整代码:

package com.yx.demo.thread; /** * DoubleInsuredThead * 双保险线程,每次启动2个相同的线程,互相检测,避免线程死锁造成影响。 *

* 两个线程都运行,但只有一个线程执行业务,但都会检测对方的时间戳 如果时间戳超过休眠时间3倍没有更新的话,则重新启动对方线程 *

* 代码例子: * 一般工作线程由自己实现,继承DoubleInsuredThead,在run2()方法里实现具体需求,和一般线程的run()方法不同,run2() * 里不用处理循环和休眠 检测线程已经由CheckThread实现,可以直接使用 * *

 *  启动用户检测线程 *  public static void startMonitor() { *  System.out.println("启动用户会话检测线程"); *  UserMonitor worker = new UserMonitor("XX-UserMonitor"); *  CheckThread checker = new CheckThread("XX-UserMonitorCheck",userMonitorIntevalTime); *  DoubleInsuredThead.startDoubleInsuredThead(worker, checker); *    } * 
* * @author yx * @date 2019/12/21 0:36 */public abstract class DoubleInsuredThead extends Thread {   /**   * 默认线程休眠时间为1000毫秒   */  public static final long DEFAULT_SLEEP_TIME = 1000;   /**   * 是否运行本线程   */  private boolean running = true;  /**   * 线程时间戳,每次run的时候更新   */  private long timeStamp = System.currentTimeMillis();  /**   * 互相检测的另外一个线程   */  DoubleInsuredThead another;   public DoubleInsuredThead(String name) {    super(name);  }   /**   * 子线程的执行业务的方法,相当于Runnable.run()方法   */  public abstract void run2();   /**   * 获得实例,重启线程的时候用   *   * @return   */  public abstract DoubleInsuredThead newInstance();   /**   * 启动工作线程,使用默认检测线程   *   * @param workerThread   */  public static void startDoubleInsuredThead(DoubleInsuredThead workerThread) {    CheckThread checkerThread =        new CheckThread(workerThread.getName() + "-checker", workerThread.getSleepTime());    workerThread.another = checkerThread;    checkerThread.another = workerThread;    workerThread.start();    checkerThread.start();  }   /**   * 自定义检测线程的方式启动工作线程,建议使用startDoubleInsuredThead(DoubleInsuredThead workerThread)   *   * @param worker 工作线程   * @param checker 检测线程   * @deprecated   */  public static void startDoubleInsuredThead(DoubleInsuredThead worker,      DoubleInsuredThead checker) {    worker.another = checker;    checker.another = worker;    worker.start();    checker.start();  }   /**   * 重启线程   */  public void restart() {    System.out.println("线程\"" + getName() + "\"重新启动了");    // 停止当前线程    running = false;    // 启动新线程    DoubleInsuredThead t = newInstance();    t.setTimeStamp(System.currentTimeMillis());    another.another = t;    t.another = another;    t.start();  }   @Override  public void run() {    while (running) {      // 执行子类线程的业务      run2();      checkAnother();      setTimeStamp(System.currentTimeMillis());       try {        Thread.sleep(getSleepTime());      } catch (InterruptedException e) {        e.printStackTrace();        System.out.println("线程休眠出错:" + e.getMessage());      }    }  }   /**   * 获得线程休眠的时间,单位毫秒   *   * @return   */  public long getSleepTime() {    return DEFAULT_SLEEP_TIME;  }   /**   * 对另外一个线程进行检测   */  private void checkAnother() {    if (another.isTimeout()) {      another.restart();    }  }   /**   * 是否更新时间戳超时   *   * @return   */  private boolean isTimeout() {    System.out.println("timeStamp = " + getTimeStamp());    return System.currentTimeMillis() - getTimeStamp() > getSleepTime() * 3;  }   /**   * @param timeStamp the timeStamp to set   */  public void setTimeStamp(long timeStamp) {    this.timeStamp = timeStamp;  }   /**   * @return the timeStamp   */  public long getTimeStamp() {    return timeStamp;  } }

检测线程:

package com.yx.demo.thread; /** * CheckThread * 双保险线程里专门用来检测的线程 * * @author yx * @date 2019/12/21 0:38 */public class CheckThread extends DoubleInsuredThead {   /**   * 检测休眠时间,默认1秒   */  private long checkIntevalTime = 1000;   public CheckThread(String name, long checkTime) {    super(name);    this.checkIntevalTime = checkTime;  }   @Override  public DoubleInsuredThead newInstance() {    return new CheckThread(getName(), checkIntevalTime);  }   @Override  public void run2() {    // 只打印信息    System.out.println("线程" + getName() + "完成了工作");  }   @Override  public long getSleepTime() {    return checkIntevalTime;  }   /**   * 测试代码   *   * @param args   */  public static void main(String[] args) {    CheckThread worker = new CheckThread("worker", 3000);    DoubleInsuredThead.startDoubleInsuredThead(worker);  }}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...