zoukankan      html  css  js  c++  java
  • 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等

  • 相关阅读:
    如何导出API文档,没有你做不到,只有你想不到!
    Oracle 数据库数据排名函数:rank() 和dense_rank() 。
    第二次绩效评估
    检查博客
    “E记”Alpha版使用说明
    绩效评估
    第一个冲刺周期意见评论
    第一个冲刺周期意见汇总
    第一次冲刺会议评审总结
    软件工程概论第一个冲刺周期
  • 原文地址:https://www.cnblogs.com/wushaopei/p/11978967.html
Copyright © 2011-2022 走看看