Java實現雙保險執行緒的示例程式碼
阿新 • • 發佈:2020-01-07
雙保險執行緒,每次啟動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個相同的執行緒,互相檢測,避免執行緒死鎖造成影響。 * <p> * 兩個執行緒都執行,但只有一個執行緒執行業務,但都會檢測對方的時間戳 如果時間戳超過休眠時間3倍沒有更新的話,則重新啟動對方執行緒 * <p> * 程式碼例子: * 一般工作執行緒由自己實現,繼承DoubleInsuredThead,在run2()方法裡實現具體需求,和一般執行緒的run()方法不同,run2() * 裡不用處理迴圈和休眠 檢測執行緒已經由CheckThread實現,可以直接使用 * * <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 { /** * 預設執行緒休眠時間為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); } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。