Call tasks sequentially and prevent deadlocks
We have an executor:
OrderedTraceExecutor executor = new OrderedTraceExecutor(Executors.newFixedThreadPool(8));
The following three lines of code (named L1, L2, L3) have the same key "foo". When they are executed in different threads in the order L2 -> L3 -> L1, we can guarantee that:
- Tasks will be executed in the order they are called in the code, with the execution order being task2 -> task3 -> task1.
- Tasks will not be executed sequentially, task3 will only execute after task2 has completed.
executor.executeAsync("foo", task1);
executor.executeAsync("foo", task2);
executor.executeAsync("foo", task3);
We have an executor:
OrderedTraceExecutor executor = new OrderedTraceExecutor(Executors.newFixedThreadPool(8));
Using executor.supply
to synchronously execute a Supplier
, the following code will not deadlock, and the value will be assigned to 1:
int value = executor.supply("foo", () -> executor.supply("bar", () -> executor.supply("foo", () -> 1)));
Perform benchmark using following machine:
Model Name: MacBook Pro
Model Identifier: MacBookPro18,1
Chip: Apple M1 Pro
Total Number of Cores: 10 (8 performance and 2 efficiency)
Memory: 16 GB
System Firmware Version: 11881.1.1
OS Loader Version: 10151.140.19.700.2
Activation Lock Status: Disabled
Execute 5,000,000 counting tasks and measure the execution time.
- TaskQueue: 620ms
- synchronized: 2336ms
- ReentrantLock: 2412ms
- RedisLockableTaskQueue: 84ms
- Lock per task: 1268ms
<dependency>
<groupId>io.github.jinganix.peashooter</groupId>
<artifactId>peashooter</artifactId>
<version>0.0.7</version>
</dependency>
implementation 'io.github.jinganix.peashooter:peashooter:0.0.7'
implementation("io.github.jinganix.peashooter:peashooter:0.0.7")
OrderedTraceExecutor executor = new OrderedTraceExecutor(Executors.newFixedThreadPool(8));
List<String> values = new ArrayList<>();
executor.executeAsync("foo", () -> values.add("1"));
executor.supply("foo", () -> values.add("2"));
executor.executeAsync("foo", () -> values.add("3"));
executor.executeSync("foo", () -> values.add("4"));
System.out.println("Values: [" + String.join(", ", values) + "]"); // Values: [1, 2, 3, 4]
If you are interested in reporting/fixing issues and contributing directly to the code base, please see CONTRIBUTING.md for more information on what we're looking for and how to get started.