Skip to content

jinganix/peashooter

Repository files navigation

CI Coverage Status License

peashooter

Call tasks sequentially and prevent deadlocks

Description

Call tasks sequentially

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);

Prevent deadlocks

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)));

Benchmark

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

Installation

Maven

<dependency>
  <groupId>io.github.jinganix.peashooter</groupId>
  <artifactId>peashooter</artifactId>
  <version>0.0.7</version>
</dependency>

Gradle (Groovy)

implementation 'io.github.jinganix.peashooter:peashooter:0.0.7'

Gradle (Kotlin)

implementation("io.github.jinganix.peashooter:peashooter:0.0.7")

Basic usage

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]

Contributing

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.