线程跳动

总览

线程jiggler是一个简单的测试框架,用于执行代码以查找线程问题。 它通过在运行时修改字节码类的类来工作,以在指令之间插入Thread.yield()调用,从而“微动”线程。 这极大地增加了发现线程问题的可能性,并且无需更改生产代码即可做到这一点。

背景

我最近正在研究如何测试多线程代码中的线程问题,并从IBM找到了一个名为ConTest的工具,但找不到我可以使用的任何代码。 很自然地,我以为我会自己加油。

考虑一下这个规范的简单但线程不安全的类:

private int count = 0 ;public void count() {count++;}

count方法的字节码为:

DUP
GETFIELD asm/Foo.counter : I
ICONST_1
IADD
PUTFIELD asm/Foo.counter : I

这提供了几个可以进行上下文切换的位置,这意味着可以增加计数,但未按预期存储。 让我们考虑一个快速的单元测试:

Counter counter = new BadCounter();int n = 1000;@Testpublic void singleThreadedTest() throws Exception {for (int i = 0; i < n; i++) {counter.count();}assertEquals(n, counter.getCount());}...

该测试在单个线程中运行并通过。 让我们尝试在两个线程上运行它,看看它是否失败。

public void threadedTest() throws Exception {final CompletionService<Void> service = new ExecutorCompletionService<Void>(Executors.newFixedThreadPool(2));for (int i = 0; i < n; i++) {service.submit(new Callable<Void>() {@Overridepublic Void call() {counter.count();return null;}});}for (int i = 0; i < n; ++i) {service.take().get();}assertEquals(n, counter.getCount());}

这也过去了。 在我的计算机上,我可以将n增加到100,000,直到它开始持续失败。

Expected :1000000
Actual   :999661

只有0.04%的测试有问题。 我们学到了什么? 我们已经学会了一种运行多线程测试的简单方法,但是我们已经知道,因为我们无法控制线程何时执行工作,所以这有点试验和错误。

线程跳动

因此,行使代码来发现线程缺陷的一个问题是您无法控制线程何时屈服。 但是,我们可以重写字节码,以便在指令之间的字节码中插入Thread.yield()。 在上面的示例中,我们可以通过更改字节码来获取产生更多问题的代码:

DUP
GETFIELD asm/Foo.counter : I
INVOKESTATIC java/lang/Thread.yield ()V
ICONST_1
IADD
PUTFIELD asm/Foo.counter : I

使用ASM,我们可以创建一个重写器来插入这些调用。 JigglingClassLoader即时重写类,添加这些调用。 由此,我们可以创建一个JUnit运行器以使用新的类加载器进行测试来运行。

@Jiggle("threadjiggler.test.*")
public class BadCounterTest {...
}

现在运行测试:

Expected :1000000
Actual   :836403

我们看到线程问题的测试数量跃升到16%。 我们无需重新编译代码,也不会影响在同一JVM中运行的其他单元测试。

读者练习

SimpleDateFormat是Java中众所周知的非线程安全类。 编写一个使类动摇的测试。 为什么它不是线程安全的? 您将如何重写它以确保线程安全? 您如何在不使用ThreadLocal,锁或同步的情况下这样做?

源代码

可以在Github上找到此代码。

进一步阅读

我写了一篇关于测试线程代码是否正确的文章 。 您可能还希望更一般地阅读:

  • 并发的错误模式及其测试方法– Eitan Farchi,Yarden Nir,Shmuel Ur IBM Haifa Research Labs
  • 介绍如何测试和调试并发软件的困难的演讲– Shmuel Ur
  • Java理论与实践:表征线程安全

参考:来自JCG合作伙伴 Alex Collins的Thread Jiggling ,位于Alex Collins的博客博客中。

翻译自: https://www.javacodegeeks.com/2013/09/thread-jiggling.html

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

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

相关文章

一套比较完整的前端技术选型,需要规整哪些东西,你知道不?

1. 背景及现状 随着前端开发复杂度的日益增加&#xff0c;各种优秀的组件框架也遍地开花。同时&#xff0c;我们面临业务规模的快速发展和工程师团队的不断扩张&#xff0c;如何解决资源整合、模块开发、项目部署、性能优化等问题势在必行。 2. 目标 根据背景和现状的分析&a…

asp.net core2.0里的Nlog

Microsoft.Extensions.Logging&#xff0c;到了Version2.0.0.0&#xff0c;没了AddNlog() ? ——我找不到输出的日志&#xff01; 。。。。。经过一番百度 step1:添加个Provider 这样&#xff0c;在Startup里Configure实现一个ILoger 如果在controller里使用&#xff1f;——…

android 回退函数,详解React Native监听Android回退按键与程序化退出应用

详解React Native监听Android回退按键与程序化退出应用发布时间&#xff1a;2020-09-29 09:25:52来源&#xff1a;脚本之家阅读&#xff1a;137作者&#xff1a;lqh详解React Native监听Android回退按键与程序化退出应用前言我们知道Android回退按键&#xff0c;会控制页面返回…

ajax 全局拦载处理,可加密、过滤、筛选、sql防注入处理

//此方法放在公用的js里面即可。如此&#xff1a;所有的ajax请求都会通过此 $.ajaxSetup({ contentType: "application/x-www-form-urlencoded;charsetutf-8", beforeSend: function() { //发送前执行的函数 try { /** * 当 processData: false,此时后台接收的值都会…

golang jwt设置过期_听说你的JWT库用起来特别扭,推荐这款贼好用的!

以前一直使用的是jjwt这个JWT库&#xff0c;虽然小巧够用, 但对JWT的一些细节封装的不是很好。最近发现了一个更好用的JWT库nimbus-jose-jwt&#xff0c;简单易用&#xff0c;API非常易于理解&#xff0c;对称加密和非对称加密算法都支持&#xff0c;推荐给大家&#xff01;简介…

亚马逊DynamoDB

介绍 Amazon DynamoDB是一项完全托管的NoSQL数据库服务&#xff0c;可提供无缝的可扩展性和快速可预测的性能。 Amazon DynamoDB自动将表的数据和流量分布在足够数量的服务器上&#xff0c;以处理客户指定的请求容量和存储的数据量&#xff0c;同时保持一致且快速的性能。 所…

随机验证码 pillow

安装 pip3 install pillow 基本使用 import PILfrom PIL import Imagefrom PIL import ImageDraw, ImageFontimport random 1.创建图片 from PIL import Image img Img.new(mode"RGB",size(120.30),color(255,255,255))# 在图片查看器中打开 # img.show()# 保存在本地…

微信小程序裁剪图片成圆形

前言 最近在开发小程序&#xff0c;产品经理提了一个需求&#xff0c;要求微信小程序换头像&#xff0c;用户剪裁图片必须是圆形&#xff0c;也在github上看了一些例子&#xff0c;一般剪裁图片用的都是方形&#xff0c;所以自己打算写一个小组件&#xff0c;可以把图片剪裁成圆…

android 系统挂载ext4格式U盘,macOS 系统下格式化 U 盘为 ext4 格式

您好&#xff0c;我是小白&#xff0c;和您请教一下哦。如果您有空QQ回复的话&#xff0c;非常感谢&#xff01;我在第一步输入完安装homebrew的命令后&#xff0c;终端报错wangneddeMBP:~ ned$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebr…

MFC控件编程之组合框跟列表框

MFC控件编程之组合框跟列表框 一丶简介 如果要使用组合框跟列表框.那么就要知道.组合框列表框是最核心的东西就是索引. 索引是从0开始的. 二丶组合框列表框常用的方法 AddString(字符串) 添加一个字符串.放到最后面. DeleteString(索引); 删除指定索引的字符串. int GetCurSe…

使用JaCoCo Maven插件为单元和集成测试创建代码覆盖率报告

当我开始使用Java 7时&#xff0c;我立即注意到Cobertura Maven插件不支持它 。 这对我来说是个大问题&#xff0c;因为我每天都使用代码覆盖率报告。 我做了一些研究&#xff0c;发现了JaCoCo代码覆盖库 。 看起来很有趣&#xff0c;我决定试一试。 问题在于配置它确实很困难…

多重继承_Python 和 Java 基础对比 10 —— 类的封装、继承和多态

Python大星一、Python 类的封装、继承和多态封装继承Python 支持多父类的继承机制&#xff0c;所以需要注意圆括号中基类的顺序&#xff0c;若是基类中有相同的方法名&#xff0c;并且在子类使用时未指定&#xff0c;Python 会从左至右搜索基类中是否包含该方法。一旦查找到则直…

前端也要会的数据结构 (不定期更新篇)

前端的软肋 一说到前端大家脑子里只有&#xff0c;布局、展示数据、修改样式等等。可是数据是哪里来的呢&#xff1f;后端给的后端给的。数据的结构呢&#xff1f;后端给啥用啥。 这就是前端的一个软肋。我们的业务让我们并不需要过深入的了解数据结构&#xff0c;数据结构和…

鸿蒙系统8月9日发布,8月9日,华为发布EMUI10.0系统+展示鸿蒙系统

8月9日&#xff0c;华为将召开华为全球开发者大会&#xff0c;本次大会邀请了5000名全球开发者、1500位合作伙伴&#xff0c;是华为历来规模最大的一次会议。在华为开发者大会上&#xff0c;华为将推出EMUI 10.0系统&#xff0c;由华为消费也业务软件总裁王成录主讲。EMUI是手机…

EclipseLink MOXy和用于JSON处理的Java API –对象模型API

用于JSON处理的Java API&#xff08;JSR-353&#xff09;是用于生成和使用JSON的Java标准&#xff0c;它是Java EE 7的一部分引入。JSR-353包括对象&#xff08;类似于DOM&#xff09;和流&#xff08;类似于StAX&#xff09;API。 在本文中&#xff0c;我将演示我们在EclipseL…

matlab main函数_Python 和MATLAB 制作Gif 图像

主要内容概述&#xff1a;预备知识MATLAB 代码实现GIF使用imageio 生成GIF使用animation 交互式方式生成GIF总结0&#xff0c;预备知识首先了解下什么是GIF 图片&#xff0c;以及常用的图片格式。GIF的全称是Graphics Interchange Format&#xff0c;可译为图形交换格式&#x…

C# MVC IOC、依赖注入

在MVC5中依赖注入&#xff0c;本文介绍通过扫描类型RegisterAssemblyTypes来进行注册 另外还有扫描模块RegisterAssemblyModules来注册 使用Autofac框架进行组件的依赖注入 Autofac是.NET领域最为流行的IOC框架之一&#xff0c;传说是速度最快的一个 先通过Nuget安装程序包 PM&…

ORB-SLAM2的特征提取算法

ORB-SLAM2跟踪线程对相机输入的每一帧图像进行跟踪处理&#xff0c;如下图所示&#xff0c;主要包括4步&#xff0c;提取ORB特征、从上一帧或者重定位来估计初始位姿、局部地图跟踪和关键帧处理。 以下结合相关理论知识&#xff0c;阅读ORB-SLAM2源代码&#xff0c;从而理解ORB…

在vue中使用SockJS实现webSocket通信

最近接到一个业务需求,需要做一个聊天信息的实时展示的界面,这就需要和服务器端建立webSocket连接,从而实现数据的实时获取和视图的实时刷新.在此将我的实现记录下来,希望可以给有同样需求的人一些帮助.废话少说,下面我就来讲一下我的实现过程: 前提 要进行文章中的代码的测试…

DI / CDI –基础

简介&#xff08;DI / CDI基础&#xff09; 首先&#xff0c;我认为对此会有一些困惑&#xff0c;但事实是&#xff0c;它们是相同的–不同之处在于用法及其用途。 DI&#xff08;依赖注入&#xff09;是通用术语–该功能基本上是在任何应用程序上进行Bean发现和Bean连接过程的…