java开发保险案例_Java实现双保险线程的示例代码

双保险线程,每次启动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);

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

相关文章

总结

以上是编程之家为你收集整理的Java实现双保险线程的示例代码全部内容,希望文章能够帮你解决Java实现双保险线程的示例代码所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

如您喜欢交流学习经验,点击链接加入交流1群:1065694478(已满)交流2群:163560250

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在ABAP Netweaver和CloudFoundry里记录并查看日志

Netweaver 要记录日志需要有一个checkpoint group&#xff0c;可以自行创建也可以使用标准的。这里我重用标准的group&#xff1a;DEMO_CHECKPOINT_GROUP。 tcode SAAB&#xff0c;点Display <->Activate进入编辑模式&#xff0c;将Logpoints设置为"Log"&#…

TiDB 源码初探

作者: 申砾 本文档面向 TiDB 社区开发者&#xff0c;主要介绍 TiDB 的系统架构、代码结构以及执行流程。 目的是使得开发者阅读文档后&#xff0c;可以对 TiDB 项目有一个整体的了解&#xff0c;更好的参与进来。首先会介绍一下大体的结构以及 Golang 包的结构&#xff0c;然后…

C#高性能低GC 非托管动态扩容数组

开始之前相比固定长度的Array&#xff0c;大家可能在编程的时候经常会使用List<T>&#xff0c;同时可能会经常往里面Add东西&#xff0c;因为List具有可扩容性&#xff0c;但是注重GC的朋友会发现&#xff08;比如Unity开发者&#xff09;&#xff0c;List.Resize会造成扩…

leetCode 53. maximum subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum. For example, given the array [-2,1,-3,4,-1,2,1,-5,4],the contiguous subarray [4,-1,2,1] has the largest sum 6. 贪婪算法找每个当前位置对应的最大的subar…

如何成为有效学习的高手(许岑)——思维导图

总结自许岑精品课《如何成为有效学习的高手》&#xff0c;图片看不清的可以看下面。 最后有彩蛋&#xff01;最后有彩蛋&#xff01;最后有彩蛋&#xff01; 定义 高效学习的定义&#xff1a;找到最适合自己的学习手法&#xff0c;在相对短的时间内集中注意力&#xff0c;以解决…

tomcat不能多次startup.sh,异常时直接,分析logs目录下的日志。

tomcat不能多次startup.sh&#xff0c;异常时直接干掉其进程。 分析logs目录下的日志。

java类sample是公共的_应在名samle.java的文件_Andoid NDK编程 1 - 注册native函数

打算对Android的NDK的开发做一总结&#xff0c;首先是JNI部分&#xff0c;接下来是NDK的内容。今天首先介绍一下JNI的第一部分&#xff1a;注册native函数。当java代码中执行native的代码时候&#xff0c;首先是通过一定的方法来找到这些native方法。而注册native函数的具体方法…

WPF Canvas 平滑笔迹

WPF Canvas 平滑笔迹控件名&#xff1a;CanvasHandWriting作者&#xff1a;小封&#xff08;邝攀升&#xff09;原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers编辑&#xff1a;驚鏵完整的思路如下收集路径点集。平均采样路径点集。将路径点集转为…

IIS应用程序池相关问题及连接池已满的解决方法

关于应用程序池 在 IIS 6.0 中,引入了应用程序池&#xff0c;应用程序池是将一个或多个应用程序链接到一个或多个工作进程集合的配置。因为应用程序池中的应用程序与其他应用程序被工作进程边界分隔&#xff0c;所以某个应用程序池中的应用程序不会受到其他应用程序池中应用程序…

echo -n 和echo -e 参数意义

echo -n 不换行输出 $echo -n "123" $echo "456" 12最终输出 123456而不是 123 456 123456echo -e 处理特殊字符 若字符串中出现以下字符&#xff0c;则特别加以处理&#xff0c;而不会将它当成一般文字输出&#xff1a; \a 发出警告声&#xff1b; \b 删…

NetSpeed

NetSpeed公司提供的NOC包括三部分&#xff0c;可以通过NocStudio进行配置生成。 1)NetSpeed Orion&#xff0c;面向快速SoC design的可综合平台。 2)Linley NetSpeed NoC面向复杂的interconnect实现&#xff0c;同时优化内部physical implementation和timing closure. NoC是基于…

js ajax java传参_ajax参数传递与后台接收

ajax参数传递与后台接收Servlet中读取http参数的方法Enumeration getParameterNames() 返回一个 String 对象的枚举&#xff0c;包含在该请求中包含的参数的名称String getParameter(String name) 以字符串形式返回请求参数的值&#xff0c;或者如果参数不存在则返回 null。Str…

init 访问器只能初始化时赋值,是真的吗?

前言C# 提供的 init 关键字用于在属性中定义访问器方法&#xff0c;可以让属性仅能在对象初始化的时候被赋值&#xff0c;其他时候只能为只读属性的形式。例如下面代码可以正常执行&#xff1a;public class Demo {public string Name { get; init; } }var demo new Demo { Na…

eclipse实现代码块折叠-类似于VS中的#region……#endregion

背 景 刚才在写代码的时候&#xff0c;写了十几行可以说是重复的代码&#xff1a; 如果整个方法或类中代码多了&#xff0c;感觉它们太TM占地方了&#xff0c;给读者在阅读代码上造成很大的困难&#xff0c;于是想到能不能把他们“浓缩”成一行&#xff0c;脑子里第一个闪现出的…

添加Chrome插件(Github上下载的压缩文件)

首先把压缩包解压到某个文件夹 然后按照以下步骤进行即可&#xff1a; 点击Chrome浏览器上的设置->扩展程序->开发者模式->点击加载已解压的压缩文件->选中解压过的文件夹确定即可。转载于:https://www.cnblogs.com/yijianzhongqing/p/6277838.html

java定义基础变量语句_java语言基础-变量

一丶变量的基本概念1.什么是变量(1).内存中的一个存储区域(2).该区域有自己的名称(变量名),和类型(数据类型)(3.)该区域的数据可以在同一类型范围内不断变化(定义变量的主要目的是因为数据的不确定性)2.为什么要定义变量用来不断存放同一类型的常量&#xff0c;并可以重复使用3…

C# WPF MVVM模式[经典]案例

01—前言Caliburn.Micro(简称CM)一经推出便备受推崇&#xff0c;作为一款MVVM开发模式的经典框架&#xff0c;越来越多的受到wpf开发者的青睐.我们看一下官方的描述&#xff1a;Caliburn是一个为Xaml平台设计的小型但功能强大的框架。Micro实现了各种UI模式&#xff0c;用于解决…

shell数组

定义数组[rootwy shell]# a(1 2 3 4)显示数组[rootwy shell]# echo ${a[]}1 2 3 4[rootwy shell]# echo ${a[*]}1 2 3 4显示数组中的某个元素[rootwy shell]# echo ${a[0]}1增加元素[rootwy shell]# a[4]9[rootwy shell]# echo ${a[*]}1 2 3 4 9修改元素值 [rootwy shell]# a[2…

java二级程序题两个角度_两个角度图_【SCME大一】使用JAVA语言深入理解程序逻辑答案_学小易找答案...

【填空题】《蝶恋花 伫倚危楼风细细 》的作者( )。【简答题】简要概述问卷调查的整体设计?【填空题】父母在,( ),游必有方。【填空题】白居易与刘禹锡并称“( )”。【填空题】白居易,字( )。【填空题】白居易,是唐代伟大的( )主义诗人。【单选题】《红楼梦》最成功处在于塑造了…

LINUX中常用操作命令

LINUX中常用操作命令 引用&#xff1a;http://www.daniubiji.cn/archives/25 Linux简介及Ubuntu安装 常见指令系统管理命令打包压缩相关命令关机/重启机器Linux管道Linux软件包管理vim使用用户及用户组管理文件权限管理Linux简介及Ubuntu安装 Linux&#xff0c;免费开源&#x…