Java并发编程 (三) 项目准备
个人博客网:https://wushaopei.github.io/ (你想要这里多有)
一、案例环境初始化
1、环境搭建与准备
Spring Boot 项目,https://start.spring.io/
Git 管理代码,https://github.com/wushaopei/concurrency
码云:https://gitee.com/wushaopei

点击Generate -Ctrl + 将项目下载到本地,并解压。
使用git bash 将码云仓库下载到本地:
git clone https://gitee.com/wushaopei/concurrency.git
将concurrency.zip压缩包解压后的src、mvnw.cmd、mvnw、pom.xml文件复制到git仓库目录concurrency下,

配置依赖驱动,加载项目

二、案例准备工作
1、自定义注解ThreadSafe.java类,用于标识线程安全的类:
/**
* @ClassName ThreadSafe
* @Description TODO
* @Author wushaopei
* @Date 2019/10/30 14:39
* @Version 1.0
* 用来标记线程安全的类或写法
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ThreadSafe {
String value() default "";
}
2、自定义注解NoThreadSafe.java类,用于标识线程不安全的类:
/**
* @ClassName NoThreadSafe
* @Description TODO
* @Author wushaopei
* @Date 2019/10/30 14:44
* @Version 1.0
* 用来标记线程不安全的类或写法
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NoThreadSafe {
String value() default "";
}
3、用来标记 不推荐 的类或者写法
/**
* 用来标记 不推荐 的类或者写法
* */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface NoRecommend {
String value() default "";
}
4、Recommend.java 用来标记 推荐 的类或者写法
/**
* 用来标记 推荐 的类或者写法
* */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Recommend {
String value() default "";
}
三、并发模拟 - 工具
常用工具:
Postman : Http请求模拟工具
Apache Bench (AB) : Apache附带的工具,测试网站性能
JMeter : Apache 组织开发的压力测试工具
代码: Semaphore 、CountDownLatch等
1、并发模拟——POSTMAN

1) 创建测试接口:
/**
* @ClassName TestController
* @Description TODO
* @Author wushaopei
* @Date 2019/10/30 15:48
* @Version 1.0
*/
@Controller
@Slf4j
public class TestController {
@RequestMapping("/test")
@ResponseBody
public String test(){
return "test";
}
}
使用POSTMAN模拟并发:
2) 新建测试用用户组:





3) 执行Run Concurrency按钮:

2、使用专业并发模拟测试工具——Apache Bench(AB)

使用ab命令指定每秒的请求数和间隔时间以及请求接口地址


3、压测工具JMeter:

jmeter文件目录下文件概览:

启动方式:
linux环境使用jmeter.sh启动脚本测试
Windows环境使用jmeter.bat启动脚本测试
使用界面:

Ramp-Up Period 代表虚拟用户增长时长,可理解为一段时间内多个用户登录的总时间范围,如8点15到9点这段时间是打卡上班的时间,也就是45分钟*60秒=2700秒
添加HTTP请求:


添加监听窗口-图形结果和察看结果树




点击绿色三角按钮启动HTTP请求

请求响应结果查看:


四、并发模拟-代码
1、 CountDownLatch (计数器向下减的闭锁)

案例解析该类的使用: 假设计数器值 cnt = 3, 线程A在调用了await()方法之后,当前线程就进入了等待状态awaiting;之后在其他进程中每次执行countDown()方法(如T1)之后计数器 cnt 就会减一,然后当前线程继续执行;之后的T2、T3一次执行完成,当计数器 cnt 变成 0之后,线程A才会继续执行。
说明: CountDownLatch这个类可以阻塞线程,并在满足某种特定条件下去执行。
2、Semaphore

假如一条公路上只有两条车道,那么同时只有两辆车可以通过同一个点;当两辆车中的其中一辆车让开以后,其他的等待的车就可以继续通过了。
说明: Semaphore可以阻塞进程,并且可以控制同一时间请求的并发量
CountDownLatch 和 Semaphore 通常会和线程池一起使用
3、并发模拟
package com.mmall.concurrency;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/**
* @ClassName ConcurrencyTest
* @Description TODO
* @Author wushaopei
* @Date 2019/10/30 16:50
* @Version 1.0
*/
@Slf4j
@NoThreadSafe //该标识表示当前线程及线程池的并发处理使用方式不正确,建议不要这么写
public class ConcurrencyTest {
//请求总数
public static int clientTotal = 5000;
// 同时并发执行的线程数
public static int threadTotal = 200;
public static int count = 0;
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0 ; i < clientTotal ; i++){
executorService.execute(()->{
try {
semaphore.acquire();
add();
semaphore.release();
}catch (Exception e){
log.error("exception",e);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown();
log.info("count:{}",count);
}
private static void add(){
count ++;
}
}
执行结果:
第一次
16:58:27.063 [main] INFO com.mmall.concurrency.ConcurrencyTest - count:4944
Process finished with exit code 0
第二次:
16:59:48.185 [main] INFO com.mmall.concurrency.ConcurrencyTest - count:4938
Process finished with exit code 0
由结果可知:程序执行结果数量少于5000,并且每次都不同。所以这是不确定的结果,存在线程安全的问题。
小结:
Postman : Http请求模拟工具
Apache Bench(AB):Apache附带的工具,测试网站性能
JMeter : Apache组织开发的压力测试工具
代码: Semaphore、CountDownLatch等
Java并发编程 (三) 项目准备的更多相关文章
- Java并发编程三个性质:原子性、可见性、有序性
并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确 线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的 ...
- 【Java并发编程三】闭锁
1.什么是闭锁? 闭锁(latch)是一种Synchronizer(Synchronizer:是一个对象,它根据本身的状态调节线程的控制流.常见类型的Synchronizer包括信号量.关卡和闭锁). ...
- Java 并发编程(三):如何保证共享变量的可见性?
上一篇,我们谈了谈如何通过同步来保证共享变量的原子性(一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行),本篇我们来谈一谈如何保证共享变量的可见性(多个线程访问同一个变 ...
- Java并发编程(三):ReentrantLock
ReentrantLock是可以用来代替synchronized的.ReentrantLock比synchronized更加灵活,功能上面更加丰富,性能方面自synchronized优化后两者性能没有 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 《Java并发编程实战》第三章 对象的共享 读书笔记
一.可见性 什么是可见性? Java线程安全须要防止某个线程正在使用对象状态而还有一个线程在同一时候改动该状态,并且须要确保当一个线程改动了对象的状态后,其它线程能够看到发生的状态变化. 后者就是可见 ...
- [Java并发编程(三)] Java volatile 关键字介绍
[Java并发编程(三)] Java volatile 关键字介绍 摘要 Java volatile 关键字是用来标记 Java 变量,并表示变量 "存储于主内存中" .更准确的说 ...
- Java并发编程原理与实战三十一:Future&FutureTask 浅析
一.Futrue模式有什么用?------>正所谓技术来源与生活,这里举个栗子.在家里,我们都有煮菜的经验.(如果没有的话,你们还怎样来泡女朋友呢?你懂得).现在女票要你煮四菜一汤,这汤是鸡汤, ...
- Java并发编程(三)volatile域
相关文章 Java并发编程(一)线程定义.状态和属性 Java并发编程(二)同步 Android多线程(一)线程池 Android多线程(二)AsyncTask源代码分析 前言 有时仅仅为了读写一个或 ...
随机推荐
- spring学习笔记(九)事务学习(上)
前述 这段时间在工作中碰到一个事务相关的问题.先说下这个问题的场景,我们是一个商城项目,正在开发优惠券模块,现在有一个需求是需要批量领取优惠券,而且在领券时,其中一张领取失败不能影响其他符合要求的 ...
- 【GISER&&规划】我这二三年
从从参加工作到现在,已经接近三年了.在这不长不短的时间里,我的职业规划犹如正余弦函数一样变化,一直游离在前端和后端之间. 第一年入职,被安排维护和拓展一套基于JAVA实现的地图瓦片生产工艺程序,不算复 ...
- 推荐算法_CIKM-2019-AnalytiCup 冠军源码解读_2
最近在为机器学习结合推荐算法的优化方法和数据来源想办法.抱着学习的态度继续解读19-AnalytiCup的冠军源码. 第一部分itemcf解读的连接:https://www.cnblogs.com/m ...
- 【FreeRTOS学习03】小白都能懂的Task Management 任务管理基本概念介绍
在FreeRTOS中,线程的术语又可以被称之为任务,或许这样更加合适,本文将介绍任务的创建/删除,任务参数的使用,以及任务优先级: 1 软实时和硬实时 硬实时系统的任务运行正确性与响应时限是紧密相关的 ...
- .NET分离exe和dll在不同的目录让你的程序更整洁
1.引言 在一个项目开发中一般都是把引用的dll放在根目录下,随着项目的日益增大,根目录下的dll文件就会越来越多,合理规划这些dll的存放地址,可以使整个项目更加的规范与美观.这篇文章就为大家介绍关 ...
- 1018 Public Bike Management (30分) 思路分析 + 满分代码
题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...
- 移动端H5支付(微信和支付宝)
我们直接进入主题吧,先说功能: 1.用户通过我们的页面输入充值帐号和金额调起支付(微信或者支付宝),支付成功返回获取支付结果. 2.微信支付成功后重定向到指定页面(没有设置重定向地址的话,默认返回调起 ...
- 设计者模式之GOF23命令模式
命令模式Command 将一个请求封装为一个对象,从而使我们可用不同的请求对客户参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.也称之为:动作Action模式,事务transaction模式 ...
- [hdu3644 A Chocolate Manufacturer's Problem]模拟退火,简单多边形内最大圆
题意:判断简单多边形内是否可以放一个半径为R的圆 思路:如果这个多边形是正多边形,令r(x,y)为圆心在(x,y)处多边形内最大圆的半径,不难发现,f(x,y)越靠近正多边形的中心,r越大,所以可以利 ...
- 基于hexo创建博客(Github托管)
基于hexo的博客 搭建好的博客网站 dengshuo7412.com 搭建步骤 1.依赖文件下载 Node.js 2.Hexo的安装 3.部署到Github 4.Hexo创建博客基本操作 5.Hex ...