Skip to content

Instantly share code, notes, and snippets.

@jonatan-ivanov
Created December 4, 2024 02:35
Show Gist options
  • Save jonatan-ivanov/cabee60d3057c238eddd0f253a9dc5fe to your computer and use it in GitHub Desktop.
Save jonatan-ivanov/cabee60d3057c238eddd0f253a9dc5fe to your computer and use it in GitHub Desktop.
Playground for ForkJoinPool, not for prod
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ForkJoinPoolDemo {
private static final int SUBMISSIONS = 10;
private static final int FORKS = 24;
private static final int PARALLELISM = 5;
private static final Duration TASK_DURATION = Duration.ofMillis(100);
private static final AtomicInteger taskCounter = new AtomicInteger();
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool(PARALLELISM);
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.submit(() -> monitor(forkJoinPool));
try {
List<ForkJoinTask<String>> tasks = new ArrayList<>();
for (int i = 0; i < SUBMISSIONS; i++) {
tasks.add(forkJoinPool.submit(new DemoTask(String.valueOf(i + 1))));
}
for (ForkJoinTask<String> task : tasks) {
printResult(task);
}
System.out.println("total tasks: " + taskCounter.get());
}
finally {
executorService.shutdownNow();
forkJoinPool.shutdown();
}
}
static void printResult(ForkJoinTask<String> task) {
try {
System.out.println(task.get());
}
catch (InterruptedException | ExecutionException e) {
System.out.println(e.getMessage());
}
finally {
task.cancel(true);
}
}
static class DemoTask extends RecursiveTask<String> {
private final String name;
private DemoTask(String name) {
this.name = name;
}
@Override
protected String compute() {
List<DemoSubTask> subTasks = new ArrayList<>();
for (int i = 0; i < FORKS; i++) {
DemoSubTask subTask = new DemoSubTask(name + "." + (i + 1));
subTask.fork();
subTasks.add(subTask);
}
sleep(TASK_DURATION);
StringBuilder result = new StringBuilder().append(String.format("%s (%d)", name, taskCounter.getAndIncrement())).append('\n');
for (DemoSubTask subTask : subTasks) {
result.append('\t').append(subTask.join()).append('\n');
}
return result.toString();
}
}
static class DemoSubTask extends RecursiveTask<String> {
private final String name;
DemoSubTask(String name) {
this.name = name;
}
@Override
protected String compute() {
sleep(TASK_DURATION);
return String.format("%s (%d)", name, taskCounter.getAndIncrement());
}
}
static void sleep(Duration duration) {
sleep(duration.toMillis());
}
static void sleep(long millis) {
try {
Thread.sleep(millis);
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
static void monitor(ForkJoinPool forkJoinPool) {
while (!Thread.currentThread().isInterrupted()) {
System.out.println(String.format(
"poolSize: %d, running: %d, active: %d, stolen: %d, qTasks: %d, qSubmissions: %d",
forkJoinPool.getPoolSize(),
forkJoinPool.getRunningThreadCount(),
forkJoinPool.getActiveThreadCount(),
forkJoinPool.getStealCount(),
forkJoinPool.getQueuedTaskCount(),
forkJoinPool.getQueuedSubmissionCount()
));
sleep(250);
}
}
}
poolSize: 0, running: 0, active: 0, stolen: 0, qTasks: 0, qSubmissions: 1
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 87, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 79, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 67, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 59, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 47, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 39, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 27, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 19, qSubmissions: 6
poolSize: 5, running: 0, active: 4, stolen: 0, qTasks: 11, qSubmissions: 6
1 (2)
1.1 (3)
1.2 (6)
1.3 (11)
1.4 (13)
1.5 (17)
1.6 (22)
1.7 (25)
1.8 (31)
1.9 (35)
1.10 (38)
1.11 (43)
1.12 (47)
1.13 (51)
1.14 (55)
1.15 (59)
1.16 (63)
1.17 (66)
1.18 (70)
1.19 (74)
1.20 (78)
1.21 (81)
1.22 (86)
1.23 (92)
1.24 (96)
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 48, qSubmissions: 4
2 (4)
2.1 (7)
2.2 (9)
2.3 (15)
2.4 (19)
2.5 (24)
2.6 (28)
2.7 (32)
2.8 (36)
2.9 (40)
2.10 (44)
2.11 (48)
2.12 (52)
2.13 (56)
2.14 (60)
2.15 (64)
2.16 (68)
2.17 (72)
2.18 (73)
2.19 (77)
2.20 (82)
2.21 (88)
2.22 (91)
2.23 (93)
2.24 (101)
3 (0)
3.1 (5)
3.2 (12)
3.3 (14)
3.4 (20)
3.5 (21)
3.6 (26)
3.7 (30)
3.8 (33)
3.9 (39)
3.10 (41)
3.11 (45)
3.12 (49)
3.13 (53)
3.14 (57)
3.15 (61)
3.16 (67)
3.17 (71)
3.18 (75)
3.19 (79)
3.20 (84)
3.21 (87)
3.22 (90)
3.23 (95)
3.24 (99)
4 (1)
4.1 (8)
4.2 (10)
4.3 (16)
4.4 (18)
4.5 (23)
4.6 (27)
4.7 (29)
4.8 (34)
4.9 (37)
4.10 (42)
4.11 (46)
4.12 (50)
4.13 (54)
4.14 (58)
4.15 (62)
4.16 (65)
4.17 (69)
4.18 (76)
4.19 (80)
4.20 (83)
4.21 (85)
4.22 (89)
4.23 (94)
4.24 (100)
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 113, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 98, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 88, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 73, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 63, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 48, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 38, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 23, qSubmissions: 1
poolSize: 5, running: 0, active: 5, stolen: 24, qTasks: 13, qSubmissions: 1
5 (98)
5.1 (103)
5.2 (108)
5.3 (116)
5.4 (121)
5.5 (122)
5.6 (128)
5.7 (133)
5.8 (138)
5.9 (142)
5.10 (147)
5.11 (152)
5.12 (158)
5.13 (163)
5.14 (168)
5.15 (172)
5.16 (177)
5.17 (183)
5.18 (188)
5.19 (192)
5.20 (197)
5.21 (203)
5.22 (208)
5.23 (213)
5.24 (217)
poolSize: 5, running: 2, active: 5, stolen: 24, qTasks: 26, qSubmissions: 0
6 (97)
6.1 (105)
6.2 (111)
6.3 (113)
6.4 (118)
6.5 (124)
6.6 (130)
6.7 (134)
6.8 (139)
6.9 (144)
6.10 (149)
6.11 (155)
6.12 (160)
6.13 (165)
6.14 (170)
6.15 (174)
6.16 (181)
6.17 (186)
6.18 (191)
6.19 (195)
6.20 (201)
6.21 (205)
6.22 (210)
6.23 (215)
6.24 (219)
7 (104)
7.1 (107)
7.2 (112)
7.3 (120)
7.4 (123)
7.5 (129)
7.6 (136)
7.7 (141)
7.8 (145)
7.9 (150)
7.10 (154)
7.11 (161)
7.12 (166)
7.13 (169)
7.14 (176)
7.15 (180)
7.16 (184)
7.17 (189)
7.18 (196)
7.19 (200)
7.20 (206)
7.21 (211)
7.22 (216)
7.23 (221)
7.24 (226)
8 (102)
8.1 (109)
8.2 (115)
8.3 (119)
8.4 (126)
8.5 (131)
8.6 (135)
8.7 (140)
8.8 (146)
8.9 (151)
8.10 (156)
8.11 (159)
8.12 (164)
8.13 (171)
8.14 (175)
8.15 (179)
8.16 (185)
8.17 (190)
8.18 (194)
8.19 (199)
8.20 (204)
8.21 (209)
8.22 (214)
8.23 (220)
8.24 (224)
9 (106)
9.1 (110)
9.2 (114)
9.3 (117)
9.4 (125)
9.5 (127)
9.6 (132)
9.7 (137)
9.8 (143)
9.9 (148)
9.10 (153)
9.11 (157)
9.12 (162)
9.13 (167)
9.14 (173)
9.15 (178)
9.16 (182)
9.17 (187)
9.18 (193)
9.19 (198)
9.20 (202)
9.21 (207)
9.22 (212)
9.23 (218)
9.24 (223)
poolSize: 5, running: 0, active: 4, stolen: 32, qTasks: 15, qSubmissions: 0
poolSize: 5, running: 0, active: 4, stolen: 32, qTasks: 6, qSubmissions: 0
10 (222)
10.1 (225)
10.2 (227)
10.3 (228)
10.4 (229)
10.5 (230)
10.6 (231)
10.7 (232)
10.8 (233)
10.9 (234)
10.10 (235)
10.11 (236)
10.12 (237)
10.13 (238)
10.14 (239)
10.15 (240)
10.16 (241)
10.17 (242)
10.18 (243)
10.19 (244)
10.20 (245)
10.21 (246)
10.22 (247)
10.23 (249)
10.24 (248)
total tasks: 250
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment