zoukankan      html  css  js  c++  java
  • 接口测试框架多线程并发线程不安全处理

    之前的接口是 Api,ApiModel,ApiHelper的形式。

    用ApiHelper专门处理api的数据加工,发送请求并获取返回。

    后来发现这种写法在单线程没问题,多线程并发下时,apiHelper处理数据会出现数据错乱。

    大致原因是apiHelper作为一个工具类,对api的所有操作都是static,就算sychronize之后,一些公用的值还是线程不安全,导致数据中途处理会串信息。

    我这边的解决办法直接把ApiHelper和Api合并了,合并后代码更简洁,一些数据的处理写起来更像流式数据的写法,而且线程控制更加安全。

    另:线上出现了一个SimpleDateFormat线程不安全的缺陷,之前一直没写demo,因为没用框架跑并发,这次并发加上了,顺便写了个demo,记录一下。

    package testdemo.junit5demo;
    
    import io.qameta.allure.Feature;
    import io.qameta.allure.Owner;
    import io.qameta.allure.Story;
    import lombok.extern.slf4j.Slf4j;
    import org.junit.jupiter.api.RepeatedTest;
    import org.junit.jupiter.api.parallel.Execution;
    import org.junit.jupiter.api.parallel.ExecutionMode;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.Date;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    //CorpStaffDataAnalyseServiceImpl
    //还有一个解决方案,手动加锁
    @Slf4j
    @Feature("SimpleDateFormat并发不安全示例")
    @Owner("zhzh.yin")
    public class ConcurrentTest {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        //StringBuffer是线程安全的,也就是多线程修改同一个StringBuffer对象的时候,过程是同步的,当然这就导致了StringBuffer的效率降低,毕竟如果要提升安全性,就必须要损失一定的效率。
        //synchronized
        //加锁
        private static final ThreadLocal<SimpleDateFormat> THREAD_LOCAL = new ThreadLocal<SimpleDateFormat>() {
            @Override
            protected SimpleDateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }
        };
    //    @RepeatedTest(500)
        @Story("并发报错:simpleDateFormat线程不安全")
        @Execution(ExecutionMode.CONCURRENT)
        //解决方案:用DateTimeFormatter
        public void testFailure() throws ParseException, InterruptedException {
            String dateString = simpleDateFormat.format(new Date());
            log.info(dateString);
            Date time = simpleDateFormat.parse(dateString);
            String dateString2 = simpleDateFormat.format(time);
            assertEquals(dateString, dateString2);
        }
    //    @RepeatedTest(500)
        @Story("解决方案:局部变量")
        @Execution(ExecutionMode.CONCURRENT)
        //解决方案:局部变量
        public void testSuc2() throws ParseException, InterruptedException {
            SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateString = simpleDateFormat1.format(new Date());
            log.info(dateString);
            Date time = simpleDateFormat1.parse(dateString);
            String dateString2 = simpleDateFormat1.format(time);
            assertEquals(dateString, dateString2);
        }
    //    @RepeatedTest(500)
        @Story("解决方案:ThreadLocal")
        @Execution(ExecutionMode.CONCURRENT)
        //解决方案:使用ThreadLocal,每个线程都拥有自己的SimpleDateFormat对象副本。
        public void testSuc3() throws ParseException, InterruptedException {
            SimpleDateFormat simpleDateFormat2 = THREAD_LOCAL.get();
            if (simpleDateFormat2 == null) {
                simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }String dateString = simpleDateFormat2.format(new Date());
            log.info(dateString);
            Date time = simpleDateFormat2.parse(dateString);
            String dateString2 = simpleDateFormat2.format(time);
            assertEquals(dateString, dateString2);
        }
    //    @RepeatedTest(500)
        @Story("解决方案:使用DateTimeFormatter")
        @Execution(ExecutionMode.CONCURRENT)
        public void testSuc1() throws ParseException, InterruptedException {
            String dateNow = LocalDateTime.now().format(dtf);
            String dateNow2=LocalDateTime.parse(dateNow,dtf).format(dtf);
            assertEquals(dateNow, dateNow2);
        }
    
    }
    

      

  • 相关阅读:
    错误处理和调试 C++快速入门30
    错误处理和调试 C++快速入门30
    虚继承 C++快速入门29
    多继承 C++快速入门28
    界面设计01 零基础入门学习Delphi42
    鱼C记事本 Delphi经典案例讲解
    界面设计01 零基础入门学习Delphi42
    虚继承 C++快速入门29
    linux系统中iptables防火墙管理工具
    linux系统中逻辑卷快照
  • 原文地址:https://www.cnblogs.com/zhizhiyin/p/13426242.html
Copyright © 2011-2022 走看看