亲宝软件园·资讯

展开

如何在匿名thread子类中保证线程安全

FunTester 人气:1

在做性能测试的过程中,我写了两个虚拟类ThreadLimitTimeCountThreadLimitTimesCount做框架,通过对线程的标记来完成超时请求的记录。旧方法如下:

 @Override
    protected void after() {
        requestMark.addAll(marks);
        marks = new ArrayList<>();
        GCThread.stop();
        synchronized (this.getClass()) {
            if (countDownLatch.getCount() == 0 && requestMark.size() != 0) {
                Save.saveStringList(requestMark, MARK_Path.replace(LONG_Path, EMPTY) + Time.getDate().replace(SPACE_1, CONNECTOR));
                requestMark = new Vector<>();
            }
        }
    }

其中我用了synchronized关键字同步,但是在匿名类的单元测试中出现一个BUG,匿名类中没有实现clone()方法,也不能直接使用深拷贝方法,导致无法直接复制对象,所以我创建了多个功能相同的匿名线程类。问题来了,在代码执行过程中,偶然会出现记录markrequest的文档中出现空内容的形式。

我查询了一些资料,感觉问题出现在synchronized (this.getClass())这个问题了,因为我打印this.getClass()给我的是当前测试类的类名,感觉原因就是匿名类的问题,匿名类相当于多个实现类,synchronized (this.getClass())无法保证多各类对象同时访问这个方法的线程安全。最终,我选择了另外一种方式,就是单独写一个线程安全的save()方法,这样就可以保证所有访问保存方法的线程的安全,将清空记录列表的功能也放在了这个线程安全的方法里了。

    /**
     * 同步save数据,用于匿名类多线程保存测试数据
     *
     * @param data
     * @param name
     */
    public static void saveStringListSync(Collection<String> data, String name) {
        synchronized (Save.class) {
            if (data.isEmpty()) return;
            saveStringList(data, name);
        }
    }

原来虚拟类的方法就变成了如下的样子:

            if (countDownLatch.getCount() == 0 && requestMark.size() != 0) {
                Save.saveStringListSync(requestMark, MARK_Path.replace(LONG_Path, EMPTY) + Time.getDate().replace(SPACE_1, CONNECTOR));
            }

  • 郑重声明:文章首发于公众号“FunTester”,禁止第三方(腾讯云除外)转载、发表。

技术类文章精选

  • java一行代码打印心形
  • Linux性能监控软件netdata中文汉化版
  • 性能测试框架第二版
  • 如何在Linux命令行界面愉快进行性能测试
  • 图解HTTP脑图
  • 将swagger文档自动变成测试代码
  • 基于java的直线型接口测试框架初探
  • Selenium 4.0 Alpha更新日志
  • Selenium 4.0 Alpha更新实践
  • 如何统一接口测试的功能、自动化和性能测试用例

非技术文章精选

  • 为什么选择软件测试作为职业道路?
  • 写给所有人的编程思维
  • 成为自动化测试的7种技能
  • 如何在DevOps引入自动化测试
  • Web端自动化测试失败原因汇总
  • 如何在DevOps引入自动化测试
  • 测试人员常用借口
  • API测试基础
  • API自动化测试指南
  • 未来的QA测试工程师

加载全部内容

相关教程
猜你喜欢
用户评论