Skip to content

Commit dae36fc

Browse files
committed
test: virtual thread + synchronized with jdk 21 vs jdk 24
1 parent 49ac269 commit dae36fc

File tree

6 files changed

+277
-0
lines changed

6 files changed

+277
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
# Carrier Thread Pinning Test
2+
3+
JEP-491 resolved Virtual Thread's carrier-thread pinning issue from JDK 24. So I tested it.
4+
5+
Ref) https://openjdk.org/jeps/491
6+
7+
## Runbook
8+
1. Download JDK 21 and 24
9+
2. Set SDK from `File > Project Structure > SDK`
10+
- ![img.png](https://github.com/user-attachments/assets/cf3dc348-f653-4b5b-ad3f-d8475fe1f962)
11+
3. Run `VirtualThreadSynchronizedTest.java` or `PlatformThreadSynchronizedTest.java`
12+
13+
## Result
14+
### JDK 21 + Platform Thread
15+
synchronized tasks doesn't block other non-synchronized tasks.
16+
```
17+
carrierThreadParallelism: 7
18+
[sync][Thread-0][9 ms] Start: 0
19+
[non-sync][Thread-1][9 ms] Start: 0
20+
[non-sync][Thread-3][9 ms] Start: 1
21+
[non-sync][Thread-5][9 ms] Start: 2
22+
[non-sync][Thread-7][9 ms] Start: 3
23+
[non-sync][Thread-9][9 ms] Start: 4
24+
[non-sync][Thread-11][10 ms] Start: 5
25+
[non-sync][Thread-13][10 ms] Start: 6
26+
[non-sync][Thread-15][10 ms] Start: 7
27+
[non-sync][Thread-17][10 ms] Start: 8
28+
[non-sync][Thread-19][10 ms] Start: 9
29+
[non-sync][Thread-21][10 ms] Start: 10
30+
[non-sync][Thread-23][10 ms] Start: 11
31+
[non-sync][Thread-25][11 ms] Start: 12
32+
[non-sync][Thread-27][11 ms] Start: 13
33+
[non-sync][Thread-1][1029 ms] End: 0
34+
[non-sync][Thread-5][1029 ms] End: 2
35+
[non-sync][Thread-7][1030 ms] End: 3
36+
[non-sync][Thread-3][1029 ms] End: 1
37+
[sync][Thread-0][1029 ms] End: 0
38+
[non-sync][Thread-9][1030 ms] End: 4
39+
[non-sync][Thread-11][1030 ms] End: 5
40+
[non-sync][Thread-13][1030 ms] End: 6
41+
[non-sync][Thread-15][1030 ms] End: 7
42+
[non-sync][Thread-23][1030 ms] End: 11
43+
[non-sync][Thread-25][1030 ms] End: 12
44+
[non-sync][Thread-17][1031 ms] End: 8
45+
[non-sync][Thread-19][1031 ms] End: 9
46+
[non-sync][Thread-21][1031 ms] End: 10
47+
[non-sync][Thread-27][1031 ms] End: 13
48+
[sync][Thread-26][1031 ms] Start: 13
49+
[sync][Thread-26][2036 ms] End: 13
50+
[sync][Thread-24][2037 ms] Start: 12
51+
[sync][Thread-24][3038 ms] End: 12
52+
[sync][Thread-22][3038 ms] Start: 11
53+
[sync][Thread-22][4043 ms] End: 11
54+
[sync][Thread-20][4044 ms] Start: 10
55+
[sync][Thread-20][5046 ms] End: 10
56+
[sync][Thread-18][5046 ms] Start: 9
57+
[sync][Thread-18][6052 ms] End: 9
58+
[sync][Thread-16][6053 ms] Start: 8
59+
[sync][Thread-16][7058 ms] End: 8
60+
[sync][Thread-14][7059 ms] Start: 7
61+
[sync][Thread-14][8060 ms] End: 7
62+
[sync][Thread-12][8061 ms] Start: 6
63+
[sync][Thread-12][9067 ms] End: 6
64+
[sync][Thread-10][9067 ms] Start: 5
65+
[sync][Thread-10][10073 ms] End: 5
66+
[sync][Thread-8][10073 ms] Start: 4
67+
[sync][Thread-8][11079 ms] End: 4
68+
[sync][Thread-6][11080 ms] Start: 3
69+
[sync][Thread-6][12085 ms] End: 3
70+
[sync][Thread-4][12086 ms] Start: 2
71+
[sync][Thread-4][13091 ms] End: 2
72+
[sync][Thread-2][13092 ms] Start: 1
73+
[sync][Thread-2][14096 ms] End: 1
74+
```
75+
76+
### JDK 21 + Virtual Thread
77+
synchronized tasks block other non-synchronized tasks: carrier-thread-pinning issue
78+
```
79+
carrierThreadParallelism: 7
80+
[sync][][11 ms] Start: 0
81+
[sync][][1029 ms] End: 0
82+
[non-sync][][11 ms] Start: 0
83+
[non-sync][][11 ms] Start: 1
84+
[non-sync][][11 ms] Start: 2
85+
[non-sync][][12 ms] Start: 3
86+
[non-sync][][12 ms] Start: 4
87+
[non-sync][][12 ms] Start: 5
88+
[non-sync][][12 ms] Start: 6
89+
[sync][][1034 ms] Start: 7
90+
[sync][][2043 ms] End: 7
91+
[sync][][2044 ms] Start: 6
92+
[sync][][3048 ms] End: 6
93+
[sync][][3049 ms] Start: 5
94+
[sync][][4054 ms] End: 5
95+
[sync][][4055 ms] Start: 4
96+
[sync][][5057 ms] End: 4
97+
[sync][][5058 ms] Start: 2
98+
[sync][][6061 ms] End: 2
99+
[non-sync][][1037 ms] Start: 7
100+
[non-sync][][2044 ms] Start: 8
101+
[non-sync][][3050 ms] Start: 9
102+
[non-sync][][4055 ms] Start: 10
103+
[non-sync][][5058 ms] Start: 11
104+
[non-sync][][6064 ms] Start: 12
105+
[sync][][6062 ms] Start: 3
106+
[sync][][7069 ms] End: 3
107+
[sync][][7070 ms] Start: 1
108+
[non-sync][][7070 ms] End: 4
109+
[non-sync][][7071 ms] End: 5
110+
[non-sync][][7071 ms] End: 6
111+
[non-sync][][7072 ms] End: 7
112+
[non-sync][][7072 ms] End: 8
113+
[non-sync][][7073 ms] End: 9
114+
[non-sync][][7073 ms] End: 10
115+
[non-sync][][7073 ms] End: 11
116+
[non-sync][][7073 ms] End: 12
117+
[non-sync][][7070 ms] Start: 13
118+
[non-sync][][7070 ms] End: 0
119+
[non-sync][][7070 ms] End: 1
120+
[non-sync][][7070 ms] End: 2
121+
[non-sync][][7070 ms] End: 3
122+
[sync][][8073 ms] End: 1
123+
[sync][][8073 ms] Start: 13
124+
[non-sync][][8075 ms] End: 13
125+
[sync][][9079 ms] End: 13
126+
[sync][][9080 ms] Start: 12
127+
[sync][][10084 ms] End: 12
128+
[sync][][10085 ms] Start: 11
129+
[sync][][11091 ms] End: 11
130+
[sync][][11092 ms] Start: 10
131+
[sync][][12095 ms] End: 10
132+
[sync][][12095 ms] Start: 9
133+
[sync][][13100 ms] End: 9
134+
[sync][][13101 ms] Start: 8
135+
[sync][][14104 ms] End: 8
136+
```
137+
138+
### JDK 24 + Virtual Thread
139+
synchronized tasks don't block other non-synchronized tasks.
140+
141+
```
142+
carrierThreadParallelism: 7
143+
[sync][][13 ms] Start: 0
144+
[non-sync][][13 ms] Start: 12
145+
[non-sync][][13 ms] Start: 13
146+
[non-sync][][13 ms] Start: 8
147+
[non-sync][][13 ms] Start: 7
148+
[non-sync][][13 ms] Start: 5
149+
[non-sync][][13 ms] Start: 6
150+
[non-sync][][13 ms] Start: 11
151+
[non-sync][][13 ms] Start: 10
152+
[non-sync][][13 ms] Start: 9
153+
[non-sync][][13 ms] Start: 4
154+
[non-sync][][13 ms] Start: 2
155+
[non-sync][][13 ms] Start: 3
156+
[non-sync][][13 ms] Start: 0
157+
[non-sync][][13 ms] Start: 1
158+
[non-sync][][1030 ms] End: 13
159+
[non-sync][][1031 ms] End: 1
160+
[non-sync][][1031 ms] End: 0
161+
[non-sync][][1031 ms] End: 3
162+
[non-sync][][1031 ms] End: 2
163+
[non-sync][][1031 ms] End: 4
164+
[non-sync][][1031 ms] End: 9
165+
[non-sync][][1031 ms] End: 10
166+
[non-sync][][1031 ms] End: 11
167+
[non-sync][][1031 ms] End: 6
168+
[non-sync][][1031 ms] End: 5
169+
[non-sync][][1031 ms] End: 7
170+
[non-sync][][1031 ms] End: 8
171+
[non-sync][][1031 ms] End: 12
172+
[sync][][1030 ms] End: 0
173+
[sync][][1038 ms] Start: 13
174+
[sync][][2043 ms] End: 13
175+
[sync][][2045 ms] Start: 11
176+
[sync][][3050 ms] End: 11
177+
[sync][][3051 ms] Start: 12
178+
[sync][][4057 ms] End: 12
179+
[sync][][4057 ms] Start: 10
180+
[sync][][5060 ms] End: 10
181+
[sync][][5061 ms] Start: 9
182+
[sync][][6066 ms] End: 9
183+
[sync][][6067 ms] Start: 8
184+
[sync][][7069 ms] End: 8
185+
[sync][][7070 ms] Start: 7
186+
[sync][][8076 ms] End: 7
187+
[sync][][8076 ms] Start: 6
188+
[sync][][9078 ms] End: 6
189+
[sync][][9079 ms] Start: 4
190+
[sync][][10084 ms] End: 4
191+
[sync][][10085 ms] Start: 5
192+
[sync][][11087 ms] End: 5
193+
[sync][][11088 ms] Start: 3
194+
[sync][][12089 ms] End: 3
195+
[sync][][12090 ms] Start: 1
196+
[sync][][13096 ms] End: 1
197+
[sync][][13097 ms] Start: 2
198+
[sync][][14098 ms] End: 2
199+
```

carrier-thread-pinning-test/build.gradle.kts

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.example;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
6+
class PlatformThreadSynchronizedTest {
7+
public static void main(String[] args) throws Exception {
8+
ExecutorService executorService = Executors.newThreadPerTaskExecutor(Thread.ofPlatform().factory());
9+
Tester tester = new Tester(executorService);
10+
tester.start();
11+
}
12+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.example;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.concurrent.ExecutorService;
6+
import java.util.concurrent.ForkJoinPool;
7+
import java.util.concurrent.Future;
8+
9+
public class Tester {
10+
private final ExecutorService executorService;
11+
12+
public Tester(ExecutorService executorService) {
13+
this.executorService = executorService;
14+
}
15+
16+
static void nonSyncLog(int i, long startTimestamp) {
17+
log("non-sync", i, startTimestamp);
18+
}
19+
20+
static synchronized void syncLog(int i, long startTimestamp) {
21+
log("sync", i, startTimestamp);
22+
}
23+
24+
private static void log(String type, int i, long startTimestamp) {
25+
System.out.printf("[%s][%s][%d ms] Start: %d\n", type, Thread.currentThread().getName(), (System.currentTimeMillis() - startTimestamp),i);
26+
try {
27+
Thread.sleep(1000);
28+
} catch (InterruptedException e) {
29+
throw new RuntimeException(e);
30+
}
31+
System.out.printf("[%s][%s][%d ms] End: %d\n", type, Thread.currentThread().getName(), (System.currentTimeMillis() - startTimestamp),i);
32+
}
33+
34+
public void start() throws Exception {
35+
long startTimestamp = System.currentTimeMillis();
36+
int carrierThreadParallelism = ForkJoinPool.commonPool().getParallelism();
37+
System.out.println("carrierThreadParallelism: " + carrierThreadParallelism);
38+
39+
List<Future<?>> futures = new ArrayList<>();
40+
41+
for (int i = 0; i < carrierThreadParallelism * 2; i++) {
42+
int finalI = i;
43+
futures.add(executorService.submit(() -> Tester.syncLog(finalI, startTimestamp)));
44+
futures.add(executorService.submit(() -> Tester.nonSyncLog(finalI, startTimestamp)));
45+
}
46+
47+
48+
for (Future<?> future : futures) {
49+
future.get();
50+
}
51+
}
52+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.example;
2+
3+
import java.util.concurrent.ExecutorService;
4+
import java.util.concurrent.Executors;
5+
6+
class VirtualThreadSynchronizedTest {
7+
8+
public static void main(String[] args) throws Exception {
9+
ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor();
10+
Tester tester = new Tester(executorService);
11+
tester.start();
12+
}
13+
}

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ include("platform-thread-api")
44
include("virtual-thread-api")
55
include("reactor-netty-api")
66
include("kotlin-coroutine-api")
7+
include("carrier-thread-pinning-test")
78
include("core")
89

910
pluginManagement {

0 commit comments

Comments
 (0)