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来重复执行用例。