Java 8使用parallel Stream测试StringBuilder线程安全

我们知道StringBuilder不是线程安全的,但如何证明它非线程安全呢?

测试StringBuilder是否线程安全一个简单的思路如下:模拟多个线程并发向StringBuilder实例添加字符,最后检测builder.toString().length()的值是否为添加字符的次数,如果非线程安全会出现builder.toString().length()的值与添加字符的次数不一致。

Java 8的Stream API提供了用于并行执行的parallel Stream,我们可以用它来模拟并发添加。

public class StringBuilderThreadSafeTest {

    @RepeatedTest(1000)
    public void testStringBuilder() {
        StringBuilder builder = new StringBuilder();
        long SIZE = 1000;
        CharSequence sequence = Stream
                .generate(() -> "a")
                .parallel()
                .limit(SIZE)
                .reduce(builder, StringBuilder::append, (b1, b2) -> b1);

        Assertions.assertEquals(SIZE,sequence.toString().length());
    }
}

因为在一次的执行中是有可能出现测试通过的情况,所以需要对测试用例执行多次。这里使用了JUnit 5的@RepeatedTest来重复执行用例。

版权声明:著作权归作者所有。

相关推荐

Java 8使用Collectors.partitioningBy分割列表

有这样一个集合:List<Integer> integers = [ 1,2,3,4,5,6,7,8,9] 现在需要把集合按奇偶数分割为两个列表。这种情况下,我们可以使用Collectors.partitioningBy来分割:Map<Boolean, List<Integer>> map =

使用Robolectric写Android单元测试

Robolectric是一个单元测试框架,运行在jvm上。相对于在Android模拟器或设备上运行测试需要花费一分甚至更长时间,Robolectric只需要几秒钟。这里简单介绍下使用Robolectric做单元测试。添加依赖首先在build.gradle添加Robolectric依赖,并设置android的测试选项unitTests.includeAndroidResources为truetest

Java 8/9使用Stream获取字符出现在字符串的索引列表

需求是这样的:输入一个字符串和一个字符,返回此字符出现在字符串里的所有索引。可以使用for循环迭代字符串可以实现此需求。考虑了下java8和java9的实现方案。java 8使用IntStream的实现方案public static List<Integer> getIndexes(String s, char c)

Java 9 Stream新增方法takeWhile的bug

Java 9的Stream新增方法takeWile():允许我们返回Stream里满足条件的前面部分元素。如:String[] arr= {"a", "b", "c","d"}; Arrays.stream(arr)     &n

Java8使用Lambda把List转换为Map

使用Java8的Collections可以很简便地把List转换为Map以User为例List里的User名字唯一Map<String, User> result =     users.stream().collect(Collectors.toMap(User::getName,   &nbs

Java 8 Stream API转换到Kotlin集合API

Kotlin提供的集合操作的API相对Java 8 Stream的API简洁很多。下面是Java 8 Stream API转换到Kotlin集合API。 映射属性聚合为列表// Java:   List<String> names = users.stream().m