Java實現(xiàn)雙保險線程的示例代碼
雙保險線程,每次啟動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 {
/**
* 默認線程休眠時間為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ù)的方法,相當于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) {
// 執(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;
}
/**
* 對另外一個線程進行檢測
*/
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);
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中使用HTTP客戶端工具Retrofit
這篇文章主要為大家介紹了SpringBoot中使用HTTP客戶端工具Retrofit方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
SpringBoot整合RedisTemplate實現(xiàn)緩存信息監(jiān)控的步驟
這篇文章主要介紹了SpringBoot整合RedisTemplate實現(xiàn)緩存信息監(jiān)控,一步一步的實現(xiàn)?Springboot?整合?Redis?來存儲數(shù)據(jù),讀取數(shù)據(jù),需要的朋友可以參考下2022-01-01
springBoot 過濾器去除請求參數(shù)前后空格實例詳解
這篇文章主要為大家介紹了springBoot 過濾器去除請求參數(shù)前后空格實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Java語言實現(xiàn)簡單FTP軟件 輔助功能模塊FTP站點管理實現(xiàn)(12)
這篇文章主要為大家詳細介紹了Java語言實現(xiàn)簡單FTP軟,輔助功能模塊FTP站點管理的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
基于SpringBoot實現(xiàn)QQ郵箱驗證碼注冊功能
QQ 郵箱是由騰訊公司推出的一款免費郵箱服務(wù),它提供了完整的郵件發(fā)送和接收功能,并且還支持多種郵件格式和附件類型,QQ 郵箱還具有強大的反垃圾郵件功能,可以有效地過濾垃圾郵件,并保護用戶隱私和安全,所以本文給大家介紹了基于SpringBoot實現(xiàn)QQ郵箱驗證碼注冊功能2024-11-11
java開源區(qū)塊鏈初始化創(chuàng)世區(qū)塊jdchain服務(wù)搭建
這篇文章主要介紹了java開源區(qū)塊鏈初始化創(chuàng)世區(qū)塊jdchain的服務(wù)搭建步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步2022-02-02

