public final class ConcurrencyTester<F,T>
extends java.lang.Object
This class is used to check whether or not a set of threads violate a concurrency contract (e.g., whether they run concurrently when they are not allowed to, or vice versa).
The following is a usage scenario of this class. Suppose we have a method that accepts an
action (of type Runnable
or the like) as an argument (e.g., methodUnderTest(...,
actionUnderTest)
) and at some point during the method's execution, the method will invoke the
action exactly once. When several threads are concurrently calling the method (possibly with
different parameter values), the method under test may make a contract that all the threads can
execute the corresponding actions concurrently, or it may make a contract that all the threads
cannot execute the actions concurrently. To check whether the method under test meets the
concurrency contract, we can write a test as follows.
ConcurrencyTester tester = new ConcurrencyTester();
for (...) {
Function actionUnderTest = (input) -> { ... };
tester.addMethodInvocationFromNewThread(
(Function anActionUnderTest) -> {
// ConcurrencyTester requires using anActionUnderTest instead of actionUnderTest
// when calling methodUnderTest
methodUnderTest(..., anActionUnderTest);
},
actionUnderTest);
}
Then, if the actions are allowed to run concurrently, we can make the following assertion:
tester.assertThatActionsCanRunConcurrently();
If the actions are not allowed to run concurrently, we can make the following assertion:
tester.assertThatActionsCannotRunConcurrently();
Constructor and Description |
---|
ConcurrencyTester() |
Modifier and Type | Method and Description |
---|---|
void |
addMethodInvocationFromNewThread(java.util.function.Consumer<java.util.function.Function<F,T>> methodUnderTestInvocation,
java.util.function.Function<F,T> actionUnderTest)
Adds a new invocation of the method under test to this
ConcurrencyTester instance. |
void |
assertThatActionsCannotRunConcurrently()
Executes the invocations of the method under test in separate threads and asserts that all
the actions ran sequentially.
|
void |
assertThatActionsCanRunConcurrently()
Executes the invocations of the method under test in separate threads and asserts that all
the actions ran concurrently.
|
void |
assertThatOnlyOneActionIsExecuted()
Executes the invocations of the method under test in separate threads and asserts that one
and only one of the actions was executed.
|
public void addMethodInvocationFromNewThread(@NonNull java.util.function.Consumer<java.util.function.Function<F,T>> methodUnderTestInvocation, @NonNull java.util.function.Function<F,T> actionUnderTest)
ConcurrencyTester
instance.
The ConcurrencyTester
will execute each invocation in a separate thread and check
whether the corresponding actions under test meet the concurrency requirement.methodUnderTestInvocation
- the invocation of the method under test which will be
executed from a new threadactionUnderTest
- the action under testpublic void assertThatActionsCanRunConcurrently()
public void assertThatActionsCannotRunConcurrently()
public void assertThatOnlyOneActionIsExecuted()