Java實(shí)現(xiàn)雙保險(xiǎn)線程的示例代碼
雙保險(xiǎn)線程,每次啟動(dòng)2個(gè)相同的線程,互相檢測(cè),避免線程死鎖造成影響。
兩個(gè)線程都運(yùn)行,但只有一個(gè)線程執(zhí)行業(yè)務(wù),但都會(huì)檢測(cè)對(duì)方的時(shí)間戳 如果時(shí)間戳超過(guò)休眠時(shí)間3倍沒(méi)有更新的話,則重新啟動(dòng)對(duì)方線程。
例子:
一般工作線程由自己實(shí)現(xiàn),繼承DoubleInsuredThead,在run2()方法里實(shí)現(xiàn)具體需求,和一般線程的run()方法不同,run2()里不用處理循環(huán)和休眠 檢測(cè)線程已經(jīng)由CheckThread實(shí)現(xiàn),可以直接使用,如:?jiǎn)?dòng)用戶檢測(cè)線程。
public static void startMonitor() {
System.out.println("啟動(dòng)用戶會(huì)話檢測(cè)線程");
UserMonitor worker = new UserMonitor("WT-UserMonitor");
CheckThread checker = new CheckThread("WT-UserMonitorCheck",userMonitorIntevalTime);
DoubleInsuredThead.startDoubleInsuredThead(worker, checker);
}
完整代碼:
package com.yx.demo.thread;
/**
* DoubleInsuredThead
* 雙保險(xiǎn)線程,每次啟動(dòng)2個(gè)相同的線程,互相檢測(cè),避免線程死鎖造成影響。
* <p>
* 兩個(gè)線程都運(yùn)行,但只有一個(gè)線程執(zhí)行業(yè)務(wù),但都會(huì)檢測(cè)對(duì)方的時(shí)間戳 如果時(shí)間戳超過(guò)休眠時(shí)間3倍沒(méi)有更新的話,則重新啟動(dòng)對(duì)方線程
* <p>
* 代碼例子:
* 一般工作線程由自己實(shí)現(xiàn),繼承DoubleInsuredThead,在run2()方法里實(shí)現(xiàn)具體需求,和一般線程的run()方法不同,run2()
* 里不用處理循環(huán)和休眠 檢測(cè)線程已經(jīng)由CheckThread實(shí)現(xiàn),可以直接使用
*
* <pre>
* 啟動(dòng)用戶檢測(cè)線程
* public static void startMonitor() {
* System.out.println("啟動(dòng)用戶會(huì)話檢測(cè)線程");
* 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)線程休眠時(shí)間為1000毫秒
*/
public static final long DEFAULT_SLEEP_TIME = 1000;
/**
* 是否運(yùn)行本線程
*/
private boolean running = true;
/**
* 線程時(shí)間戳,每次run的時(shí)候更新
*/
private long timeStamp = System.currentTimeMillis();
/**
* 互相檢測(cè)的另外一個(gè)線程
*/
DoubleInsuredThead another;
public DoubleInsuredThead(String name) {
super(name);
}
/**
* 子線程的執(zhí)行業(yè)務(wù)的方法,相當(dāng)于Runnable.run()方法
*/
public abstract void run2();
/**
* 獲得實(shí)例,重啟線程的時(shí)候用
*
* @return
*/
public abstract DoubleInsuredThead newInstance();
/**
* 啟動(dòng)工作線程,使用默認(rèn)檢測(cè)線程
*
* @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();
}
/**
* 自定義檢測(cè)線程的方式啟動(dòng)工作線程,建議使用startDoubleInsuredThead(DoubleInsuredThead workerThread)
*
* @param worker 工作線程
* @param checker 檢測(cè)線程
* @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)了");
// 停止當(dāng)前線程
running = false;
// 啟動(dòng)新線程
DoubleInsuredThead t = newInstance();
t.setTimeStamp(System.currentTimeMillis());
another.another = t;
t.another = another;
t.start();
}
@Override
public void run() {
while (running) {
// 執(zhí)行子類(lèi)線程的業(yè)務(wù)
run2();
checkAnother();
setTimeStamp(System.currentTimeMillis());
try {
Thread.sleep(getSleepTime());
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("線程休眠出錯(cuò):" + e.getMessage());
}
}
}
/**
* 獲得線程休眠的時(shí)間,單位毫秒
*
* @return
*/
public long getSleepTime() {
return DEFAULT_SLEEP_TIME;
}
/**
* 對(duì)另外一個(gè)線程進(jìn)行檢測(cè)
*/
private void checkAnother() {
if (another.isTimeout()) {
another.restart();
}
}
/**
* 是否更新時(shí)間戳超時(shí)
*
* @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;
}
}
檢測(cè)線程:
package com.yx.demo.thread;
/**
* CheckThread
* 雙保險(xiǎn)線程里專(zhuān)門(mén)用來(lái)檢測(cè)的線程
*
* @author yx
* @date 2019/12/21 0:38
*/
public class CheckThread extends DoubleInsuredThead {
/**
* 檢測(cè)休眠時(shí)間,默認(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;
}
/**
* 測(cè)試代碼
*
* @param args
*/
public static void main(String[] args) {
CheckThread worker = new CheckThread("worker", 3000);
DoubleInsuredThead.startDoubleInsuredThead(worker);
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:如何基于SpringBoot部署外部Tomcat過(guò)程解析
欄 目:Java
下一篇:Java搭建RabbitMq消息中間件過(guò)程詳解
本文標(biāo)題:Java實(shí)現(xiàn)雙保險(xiǎn)線程的示例代碼
本文地址:http://www.jygsgssxh.com/a1/Java/8917.html
您可能感興趣的文章
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10淺談Java中真的只有值傳遞么
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問(wèn)題


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)模擬時(shí)鐘
- 01-10Springboot中@Value的使用詳解
- 01-10JavaWeb實(shí)現(xiàn)郵件發(fā)送功能
- 01-10利用Java實(shí)現(xiàn)復(fù)制Excel工作表功能
- 01-10Java實(shí)現(xiàn)動(dòng)態(tài)數(shù)字時(shí)鐘
- 01-10java基于poi導(dǎo)出excel透視表代碼實(shí)例
- 01-10java實(shí)現(xiàn)液晶數(shù)字字體顯示當(dāng)前時(shí)間
- 01-10基于Java驗(yàn)證jwt token代碼實(shí)例
- 01-10Java動(dòng)態(tài)顯示當(dāng)前日期和時(shí)間
- 01-10淺談Java中真的只有值傳遞么
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?


