溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java實現(xiàn)雙保險線程的示例代碼

發(fā)布時間:2020-09-13 04:05:14 來源:腳本之家 閱讀:139 作者:IT_熊 欄目:編程語言

雙保險線程,每次啟動2個相同的線程,互相檢測,避免線程死鎖造成影響。

兩個線程都運行,但只有一個線程執(zhí)行業(yè)務(wù),但都會檢測對方的時間戳 如果時間戳超過休眠時間3倍沒有更新的話,則重新啟動對方線程。

例子:

一般工作線程由自己實現(xiàn),繼承DoubleInsuredThead,在run2()方法里實現(xiàn)具體需求,和一般線程的run()方法不同,run2()里不用處理循環(huán)和休眠 檢測線程已經(jīng)由CheckThread實現(xiàn),可以直接使用,如:啟動用戶檢測線程。

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個相同的線程,互相檢測,避免線程死鎖造成影響。
 * <p>
 * 兩個線程都運行,但只有一個線程執(zhí)行業(yè)務(wù),但都會檢測對方的時間戳 如果時間戳超過休眠時間3倍沒有更新的話,則重新啟動對方線程
 * <p>
 * 代碼例子:
 * 一般工作線程由自己實現(xiàn),繼承DoubleInsuredThead,在run2()方法里實現(xiàn)具體需求,和一般線程的run()方法不同,run2()
 * 里不用處理循環(huán)和休眠 檢測線程已經(jīng)由CheckThread實現(xiàn),可以直接使用
 *
 * <pre>
 *  啟動用戶檢測線程
 *  public static void startMonitor() {
 *  System.out.println("啟動用戶會話檢測線程");
 *  UserMonitor worker = new UserMonitor("XX-UserMonitor");
 *  CheckThread checker = new CheckThread("XX-UserMonitorCheck",userMonitorIntevalTime);
 *  DoubleInsuredThead.startDoubleInsuredThead(worker, checker);
 *    }
 * </pre>
 *
 * @author yx
 * @date 2019/12/21 0:36
 */
public abstract class DoubleInsuredThead extends Thread {
 
  /**
   * 默認(rèn)線程休眠時間為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);
  }
 
  /**
   * 子線程的執(zhí)行業(yè)務(wù)的方法,相當(dāng)于Runnable.run()方法
   */
  public abstract void run2();
 
  /**
   * 獲得實例,重啟線程的時候用
   *
   * @return
   */
  public abstract DoubleInsuredThead newInstance();
 
  /**
   * 啟動工作線程,使用默認(rèn)檢測線程
   *
   * @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() + "\"重新啟動了");
    // 停止當(dāng)前線程
    running = false;
    // 啟動新線程
    DoubleInsuredThead t = newInstance();
    t.setTimeStamp(System.currentTimeMillis());
    another.another = t;
    t.another = another;
    t.start();
  }
 
  @Override
  public void run() {
    while (running) {
      // 執(zhí)行子類線程的業(yè)務(wù)
      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;
  }
 
  /**
   * 對另外一個線程進(jìn)行檢測
   */
  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 {
 
  /**
   * 檢測休眠時間,默認(rèn)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);
  }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI