漫画编程java_【漫画】JAVA并发编程之并发模拟工具
上一节【漫画】JAVA并发编程三大Bug源头(可见性、原子性、有序性)我们聊了聊并发编程的三个bug源头,这还没开始进入并发世界,胖滚猪就遇到了难题。。
这个难题是所有初学者都会有的疑惑:没法复现那些理论知识告诉我们的bug。但是实际操练很重要,那么在本地开发环境,到底应该怎样模拟并发呢?
模拟并发工具大全
在本地模拟并发环境的方法有挺多的,比较热门的有以下几种,包括工具和代码:
1、Postman:Http请求模拟工具,可以设置发起N个请求(但不推荐,并不专业)
2、Apache Bench(AB):Apache 服务器的一个web压力测试工具,是一个命令行工具,可根据命令创建很多并发访问线程,模拟多个访问者同时对某一个URL地址进行访问。总体来说,ab工具小巧简单,上手学习较快,可以提供需要的基本性能指标;但是缺点就是没有图形化结果,不能监控。
3、Apache JMeter:Apache组织开发的基于Java的压力测试工具。功能相比AB会更加强大,尤其是有GUI图形化界面,这一点很爽。另外jmeter是一次完整的请求和返回;AB只是发出去请求,并不对返回做处理。如果你希望看到返回结果,那么也应该选择JMeter。
4、JAVA代码:包括CountDownLatch、CyclicBarrier等
我们主要说一下如何通过jmeter和代码来模拟并发环境,也推荐使用这两种方式。
CountDownLatch(等待多线程完成)
原创声明:本文来源于公众号【胖滚猪学编程】,转载请注明出处。
countDownLatch是在java1.5被引入,存在于java.util.cucurrent包下。
这个类能使一个线程等待其他线程各自执行完毕后再执行。
它是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
如图所示,初始值cnt=3,线程A执行了await方法所以被阻塞等待,T1\T2\T3线程通过调用countDown,让计数器减一,直到cnt=0后,Thread A才恢复运行。换句话说就是,Thread A需要等待其他三个线程都执行完才能执行:
countDownLatch类中只提供了一个构造器:
//参数count为计数值
public CountDownLatch(int count) { };
countDownLatch类中有三个方法是最重要的:
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
//将count值减1
public void countDown() { };
举例:需求是处理一个Excel,Excel有很多行数据,为了效率,我们可以使用多线程处理,但是处理完所有行数据后,需要通知到主线程。如果没有countDownLatch,那么效果是这样的,还没处理完呢你就说我结束了:
如果在主线程上加上countDownLatch,并且调用await()方法,那么主线程会被挂起,它会等待直到count值为0才继续执行:
static CountDownLatch countDownLatch = new CountDownLatch(100);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
Thread thread = new Thread(() -> {
doWork();
countDownLatch.countDown();
});
thread.start();
}
countDownLatch.await();
System.out.println("处理完整个excel的结束时间"+System.currentTimeMillis());
}
public static void doWork(){
System.out.println("处理行数据,时间"+System.currentTimeMillis());
}
Thread thread = new Thread(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
doWork();
});
thread.start();
countDownLatch.countDown();
线程池
ExecutorService executorService = new ThreadPoolExecutor(100,
200, 60, TimeUnit.MINUTES, new ArrayBlockingQueue(20000), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
});
CyclicBarrier(同步屏障)
原创声明:本文来源于公众号【胖滚猪学编程】,转载请注明出处。
CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
如下图所示,一共4个线程A、B、C、D,它们到达屏障的顺序可能各不相同。当A、B、C到达栅栏后,由于没有满足总数【4】的要求,所以会一直等待,当线程D到达后,栅栏才会放行。
CyclicBarrier构造方法
//其参数表示屏障拦截的线程数量
public CyclicBarrier(int parties)
//多了回调函数
public CyclicBarrier(int parties, Runnable barrierAction)
主要方法如下
//调用await方法的线程告诉CyclicBarrier自己已经到达同步点,然后当前线程被阻塞。直到parties个参与线程调用了await方法,阻塞线程才会执行。
public int await()
//带超时时间参数
public int await(long timeout, TimeUnit unit)
//重置
public void reset()
根据这一特性,我们也可以用于并发模拟,如下代码就是模拟了5个线程并发执行:
private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = ExecutorServiceUtils.getExecutor();
for (int i = 0; i < 20; i++) {
int finalI = i;
Thread.sleep(1000);
executorService.submit(() -> {
try {
doWork(finalI);
} catch (Exception e) {
e.printStackTrace();
}
});
//通过打印日志 得出它具有自动重置功能
log.info("Parties={} 等待中{}",cyclicBarrier.getParties(),cyclicBarrier.getNumberWaiting());
}
executorService.shutdown();
}
public static void doWork(Integer threadNum) throws Exception {
Thread.sleep(1000);
log.info("{} is ready", threadNum);
cyclicBarrier.await();
log.info("{} continue", threadNum);
}
CountDownLatch 和 CyclicBarrier 的主要区别:
1、CountDownLatch 主要用来解决一个线程等待多个线程的场景,可以类比旅游团团长要等待所有的游客到齐才能去下一个景点;
而CyclicBarrier 是一组线程之间互相等待,更像是几个驴友之间不离不弃。
2、CountDownLatch是减计数方式,而CyclicBarrier是加计数方式。
3、CountDownLatch 的计数器是不能循环利用的,也就是说一旦计数器减到 0,再有线程调用 await(),该线程会直接通过。
但CyclicBarrier 的计数器是可以循环利用的,而且具备自动重置的功能,一旦计数器减到 0 会自动重置到你设置的初始值。
4、除此之外,CyclicBarrier 还可以设置回调函数,可以说是功能丰富。而CountDownLatch不支持回调函数。
好了,现在再回到最开头那段无法复现的代码,我们用CyclicBarrier来改写一下,你就可以看到出现0的情况了。
另外还要说一点:即使是真正的并发执行了,出问题依旧是小概率事件,本人亲测运行了15次才出现0的结果。运气不好可能运行100次还是不会看到。不必太过于纠结这些哦!
JMeter工具
1、下载好后解压目录,配置环境变量,运行jmeter.bat即可
2、添加一个线程组:
3、配置线程组相关属性,主要是线程数量以及是否循环,这里我们设置并发线程数是50,执行完每个线程后不需要循环:
4、添加http请求,比如我们要测试/test接口的请求:
配置http ip\端口\编码格式等:
5、添加两个监听器、用于执行结束后查看图形结果和查看结果数:
6、运行线程组,就可以输出我们的结果了
好了,今天就到这里了,又到了要跟大家说拜拜的时候了~
原创声明:本文来源于公众号【胖滚猪学编程】,转载请注明出处。
漫画编程java_【漫画】JAVA并发编程之并发模拟工具相关推荐
- aqs clh java_【Java并发编程实战】—– AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...
- Java并发编程的艺术-Java并发编程基础
第4章 Java并发编程基础 Java从诞生开始就明智地选择了内置对多线程的支持,这使得Java语言相比同一时期的其他语言具有明显的优势.线程作为操作系统调度的最小单元,多个线程能够同时执行,这将 ...
- phaser java_【Java并发编程实战】-----“J.U.C”:Phaser
Phaser由java7中推出,是Java SE 7中新增的一个使用同步工具,在功能上面它与CyclicBarrier.CountDownLatch有些重叠,但是它提供了更加灵活.强大的用法. Cyc ...
- java任何封闭实例都不是java_《java并发编程实战》读书笔记3--对象的组合
希望将一些现有的线程安全组件组合为更大规模的组件或程序 设计线程安全的类 如果对象中所有的域是基本类型变量,那么这些域将构成对象的全部状态.例如,LinkedList的状态就包括该链表中所有节点对象的 ...
- aqs clh java_【Java并发编程实战】----- AQS(一):简介
在前面博客中,LZ讲到了ReentrantLock.ReentrantReadWriteLock.Semaphore.CountDownLatch,他们都有各自获取锁的方法,同时相对于Java的内置锁 ...
- Java并发编程实战_[Java并发编程实战] 简介
并发简史 在早期不包含操作系统的计算机中,程序都是单一的串行程序,从头至尾只能执行一个程序,并且这个程序访问这个计算机的所有资源.然而,随着技术的发展,操作系统出现了.它使得计算机程序有了进程,线程的 ...
- java硬件编程_关于JAVA并发编程你需要知道的——硬件篇
无论程序语言如何千变万化,他们都深深地根植于目前的计算机体系结构. 左图是intel CPU的三级高速缓存设计,由于高速缓存对程序员基本不可见,因此可以抽象为右图. 缓存的设计 首先还是先谈谈左图. ...
- Java并发编程—常见面试题
建议: 学习java并发前需要先掌握JVM知识 关于下面问题档案的详细解析都在后面推荐的相关系列文章中 一.线程安全相关 1.什么叫线程安全? 线程安全就是说多线程访问同一代码,不会产生不确定的结果. ...
- Java并发编程系列
Java并发编程系列 2018-03-08 Java 并发编程:核心理论 Java并发编程:Synchronized及其实现原理 Java并发编程:Synchronized底层优化(轻量级锁.偏向锁) ...
- 我肝了2个月,为你整理了Java并发编程手册
从原理到实战,全面讲解Java并发编程核心知识,你值得拥有的Java并发编程手册. 如何看待程序员35岁职业危机? Java全套学习资料(14W字),耗时半年整理 我肝了三个月,为你写出了GO核心手册 ...
最新文章
- 香港中文大学(深圳)吴保元教授课题组招收全奖PhD、实习/访问学生
- 强弱AI的辩论:关于人工智能意识的奇妙理论
- java juc exchanger_JUC工具类实例
- java.text._Java.text
- python exe运行报 编码错误_python运行显示编码错误
- 使用Postgrest快速创建数据库的OpenAPI接口
- 亲爱的,你是最棒的!
- linux 线程管理、同步机制等
- python入门小游戏之跳一跳_从零基础开始,用python手把手教你玩跳一跳小游戏,直接打出高分...
- 荔枝图床阿里掘金搜狗奇虎图床源码
- idea的英文是什么意思_德芙和多芬的英文都是Dove!“Dove”究竟是什么意思?
- 第一公会强势分析《TmoLand》快速回本玩法
- MyEclipse从数据库反向生成实体类通过Hibernate的方式----mysql数据库实例
- 灵山奇缘服务器维护,灵山奇缘1月8日更新了什么 灵山奇缘1月8日更新维护内容一览...
- Python爬虫开发【第1篇】【urllib2】
- 用计算机算标准曲线,标准曲线计算器官方版
- Android Studio ADB 命令大全
- 小米 OJ 编程比赛 02 月常规赛 (Carryon 数数字)
- JAVA中成员变量和局部变量区别
- Deepin 深度技术 Windows XP SP2 珍藏版
热门文章
- 深信服防火墙console波特率_深信服防火墙AF上arp表数量限制导致网络问题的处理说明...
- Hadoop生态圈(六)- HDFS NAMENODE 安全模式
- python编程—猜数字小游戏
- Python txt文件转成xlsx文件
- 泰坦尼克号生存率分析
- X86架构CPU常识(主频,外频,FSB,cpu位和字长,倍频系数,缓存,CPU扩展指令集,CPU内核和I/O工作电压,制造工艺,指令集,超流水线与超标量)...
- Shiro内部过滤器执行顺序
- .NET Framework 3.5弹出错误代码0x800f0954解决方法
- C# 网络斗地主源码开源
- 关于地产信息化“大佬”们说了什么?看完这些就够了