Skip to content

Commit 5286706

Browse files
committed
initial commit
1 parent a501259 commit 5286706

11 files changed

+607
-0
lines changed

pom.xml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.github.forax.threadstop</groupId>
8+
<artifactId>threadstop</artifactId>
9+
<version>0.1</version>
10+
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
</properties>
14+
15+
<dependencies>
16+
<dependency>
17+
<groupId>org.junit.jupiter</groupId>
18+
<artifactId>junit-jupiter-api</artifactId>
19+
<version>5.10.2</version>
20+
<scope>test</scope>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.junit.jupiter</groupId>
24+
<artifactId>junit-jupiter-engine</artifactId>
25+
<version>5.10.2</version>
26+
<scope>test</scope>
27+
</dependency>
28+
29+
<dependency>
30+
<groupId>org.openjdk.jmh</groupId>
31+
<artifactId>jmh-core</artifactId>
32+
<version>1.37</version>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.openjdk.jmh</groupId>
36+
<artifactId>jmh-generator-annprocess</artifactId>
37+
<version>1.37</version>
38+
<scope>provided</scope>
39+
</dependency>
40+
</dependencies>
41+
42+
<build>
43+
<plugins>
44+
<plugin>
45+
<groupId>org.apache.maven.plugins</groupId>
46+
<artifactId>maven-compiler-plugin</artifactId>
47+
<version>3.13.0</version>
48+
<configuration>
49+
<release>22</release>
50+
<compilerArgs>--enable-preview</compilerArgs>
51+
<annotationProcessorPaths>
52+
<path>
53+
<groupId>org.openjdk.jmh</groupId>
54+
<artifactId>jmh-generator-annprocess</artifactId>
55+
<version>1.37</version>
56+
</path>
57+
</annotationProcessorPaths>
58+
</configuration>
59+
</plugin>
60+
61+
<plugin>
62+
<groupId>org.apache.maven.plugins</groupId>
63+
<artifactId>maven-surefire-plugin</artifactId>
64+
<version>3.2.5</version>
65+
<configuration>
66+
<argLine>--enable-preview</argLine>
67+
</configuration>
68+
</plugin>
69+
70+
<plugin>
71+
<groupId>org.apache.maven.plugins</groupId>
72+
<artifactId>maven-shade-plugin</artifactId>
73+
<version>3.5.2</version>
74+
<executions>
75+
<execution>
76+
<phase>package</phase>
77+
<goals>
78+
<goal>shade</goal>
79+
</goals>
80+
<configuration>
81+
<finalName>benchmarks</finalName>
82+
<transformers>
83+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
84+
<mainClass>org.openjdk.jmh.Main</mainClass>
85+
</transformer>
86+
</transformers>
87+
<filters>
88+
<filter>
89+
<artifact>*:*</artifact>
90+
<excludes>
91+
<exclude>**/module-info.class</exclude>
92+
<exclude>META-INF/MANIFEST.MF</exclude>
93+
</excludes>
94+
</filter>
95+
</filters>
96+
</configuration>
97+
</execution>
98+
</executions>
99+
</plugin>
100+
</plugins>
101+
</build>
102+
103+
</project>

src/main/java/_0_no_stop.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
boolean stop;
2+
3+
void loop() {
4+
while(true) {
5+
if (stop) {
6+
break;
7+
}
8+
// global warming
9+
}
10+
System.out.println("end !");
11+
}
12+
13+
void main() throws InterruptedException {
14+
var thread = new Thread(this::loop);
15+
thread.start();
16+
17+
Thread.sleep(1_000);
18+
stop = true;
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
boolean stop;
2+
final Object lock = new Object();
3+
4+
void loop() {
5+
while(true) {
6+
synchronized (lock) {
7+
if (stop) {
8+
break;
9+
}
10+
}
11+
// global warming
12+
}
13+
System.out.println("end !");
14+
}
15+
16+
void main() throws InterruptedException {
17+
var thread = new Thread(this::loop);
18+
thread.start();
19+
20+
Thread.sleep(1_000);
21+
synchronized (lock) {
22+
stop = true;
23+
}
24+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import java.util.concurrent.locks.ReentrantLock;
2+
3+
boolean stop;
4+
final ReentrantLock lock = new ReentrantLock();
5+
6+
void loop() {
7+
while(true) {
8+
lock.lock();
9+
try {
10+
if (stop) {
11+
break;
12+
}
13+
} finally {
14+
lock.unlock();
15+
}
16+
// global warming
17+
}
18+
System.out.println("end !");
19+
}
20+
21+
void main() throws InterruptedException {
22+
var thread = new Thread(this::loop);
23+
thread.start();
24+
25+
Thread.sleep(1_000);
26+
lock.lock();
27+
try {
28+
stop = true;
29+
} finally {
30+
lock.unlock();
31+
}
32+
}

src/main/java/_3_stop_interrupt.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
void loop() {
2+
while(true) {
3+
if (Thread.interrupted()) {
4+
break;
5+
}
6+
// global warming
7+
}
8+
System.out.println("end !");
9+
}
10+
11+
void main() throws InterruptedException {
12+
var thread = new Thread(this::loop);
13+
thread.start();
14+
15+
Thread.sleep(1_000);
16+
thread.interrupt();
17+
}

src/main/java/_4_stop_volatile.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
volatile boolean stop;
2+
3+
void loop() {
4+
while(true) {
5+
if (stop) {
6+
break;
7+
}
8+
// global warming
9+
}
10+
System.out.println("end !");
11+
}
12+
13+
void main() throws InterruptedException {
14+
var thread = new Thread(this::loop);
15+
thread.start();
16+
17+
Thread.sleep(1_000);
18+
stop = true;
19+
}

src/main/java/_5_stop_opaque.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import java.lang.invoke.MethodHandles;
2+
import java.lang.invoke.VarHandle;
3+
4+
static final VarHandle STOP = createVH();
5+
6+
private static VarHandle createVH() {
7+
var lookup = MethodHandles.lookup();
8+
try {
9+
return lookup.findVarHandle(lookup.lookupClass(), "stop", boolean.class);
10+
} catch (NoSuchFieldException | IllegalAccessException e) {
11+
throw new AssertionError(e);
12+
}
13+
}
14+
15+
boolean stop;
16+
17+
void loop() {
18+
while(true) {
19+
var stop = (boolean) STOP.getOpaque(this);
20+
if (stop) {
21+
break;
22+
}
23+
// global warming
24+
}
25+
System.out.println("end !");
26+
}
27+
28+
void main() throws InterruptedException {
29+
var thread = new Thread(this::loop);
30+
thread.start();
31+
32+
Thread.sleep(1_000);
33+
STOP.setOpaque(this, true);
34+
}

src/main/java/_6_stop_callsite.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.lang.invoke.MethodHandle;
2+
import java.lang.invoke.MethodHandles;
3+
import java.lang.invoke.MethodType;
4+
import java.lang.invoke.MutableCallSite;
5+
6+
static final class Stop extends MutableCallSite {
7+
public Stop() {
8+
super(MethodType.methodType(boolean.class));
9+
setTarget(MethodHandles.constant(boolean.class, false));
10+
}
11+
}
12+
13+
static final Stop STOP = new Stop();
14+
static final MethodHandle STOP_MH = STOP.dynamicInvoker();
15+
16+
void loop() {
17+
while(true) {
18+
boolean stop;
19+
try {
20+
stop = (boolean) STOP_MH.invokeExact();
21+
} catch (RuntimeException | Error e) {
22+
throw e;
23+
} catch (Throwable e) {
24+
throw new AssertionError(e);
25+
}
26+
if (stop) {
27+
break;
28+
}
29+
// global warming
30+
}
31+
System.out.println("end !");
32+
}
33+
34+
void main() throws InterruptedException {
35+
var thread = new Thread(this::loop);
36+
thread.start();
37+
38+
Thread.sleep(1_000);
39+
STOP.setTarget(MethodHandles.constant(boolean.class, true));
40+
MutableCallSite.syncAll(new MutableCallSite[] { STOP });
41+
}

src/main/java/_7_stop_arena.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import java.lang.foreign.Arena;
2+
import java.lang.foreign.MemorySegment;
3+
4+
final Arena arena = Arena.ofShared();
5+
final MemorySegment.Scope scope = arena.scope();
6+
7+
void loop() {
8+
while(true) {
9+
if (!scope.isAlive()) {
10+
break;
11+
}
12+
// global warming
13+
}
14+
System.out.println("end !");
15+
}
16+
17+
void main() throws InterruptedException {
18+
var thread = new Thread(this::loop);
19+
thread.start();
20+
21+
Thread.sleep(1_000);
22+
arena.close();
23+
}

0 commit comments

Comments
 (0)