0

Threads Collider:一个Java多线程测试工具

 1 month ago
source link: https://www.jdon.com/71786.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Threads Collider:一个Java多线程测试工具

Threads Collider尝试在“完全相同”的时刻对多个线程执行所需的操作,以增加出现由竞争条件或死锁引起的问题的机会。

code@RepeatedTest(10)
void Thread_safe_adding_to_list() {
    // Given
    List<String> list = new ArrayList<>();    // <-- NOT thread safe

    // When
    try (ThreadsCollider threadsCollider =
             threadsCollider()
                 .withAction(() -> list.add("bar"))
                 .times(Processors.ALL)   // run action on all available processors
                 .build()) {

        threadsCollider.collide();
    }

    // Then
    then(list).hasSize(Processors.ALL).containsOnly("bar");
}/code

死锁测试:
codevoid update1(List<Integer> list1, List<Integer> list2) {

    synchronized (list1) {
        list1.add(1);
        synchronized (list2) {
            list2.add(1);
        }
    }
}
void update2(List<Integer> list2, List<Integer> list1) {

    synchronized (list2) {
        list2.add(1);
        synchronized (list1) {
            list1.add(1);
        }
    }
}/code

希望同时执行这两个方法以显示死锁:

code@RepeatedTest(10)
void Detect_deadlock() {
    // Given
    List<Exception> exceptions = new ArrayList<>();

    // When
    try (ThreadsCollider collider =
             threadsCollider()
                 .withAction(() -> update1(list1, list2), "update1") // add action name for better logs readability
                 .times(Processors.HALF)
                 .withAction(() -> update2(list2, list1), "update2") // add action name for better logs readability
                 .times(Processors.HALF)
                 .withThreadsExceptionsConsumer(exceptions::add)     // save threads exceptions
                 .withAwaitTerminationTimeout(100)
                 .asMilliseconds()
                 .build()) {

        collider.collide();
    }

    // Then
    then(exceptions).isEmpty();
}/code
某些测试将失败并显示以下消息:
codejava.lang.AssertionError: 
Expecting empty but was: pl.amazingcode.threadscollider.UnfinishedThreads: 
There are threads that have not completed within the specified timeout: 100 MILLISECONDS
Check if there are any deadlocks and fix them. 
If there are no deadlocks, increase timeout.
Deadlocked threads:
"collider-pool-thread-2 update1" daemon prio=5 Id=24 BLOCKED on java.util.ArrayList@6c6cb480 owned by "collider-pool-thread-3 update2" Id=25

"collider-pool-thread-3 update2" daemon prio=5 Id=25 BLOCKED on java.util.ArrayList@3eb738bb owned by "collider-pool-thread-2 update1" Id=24

/code

依赖:
code<dependency>
    <groupId>pl.amazingcode</groupId>
    <artifactId>threads-collider</artifactId>
    <version>1.0.3</version>
    <scope>test</scope>
</dependency>/code


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK