-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.java
124 lines (111 loc) · 3.82 KB
/
Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Main implements Runnable {
public static void main(String[] args) throws InterruptedException, IOException {
var t = new Thread(new Main());
try (jdk.jfr.Recording recording = new jdk.jfr.Recording()) {
recording.setName("test");
recording.setDumpOnExit(true);
recording.setDestination(Path.of("./out.jfr"));
recording.enable(CustomEvent.class);
recording.enable(CollectionSizeEvent.class);
recording.setToDisk(true);
recording.start();
t.setDaemon(false);
t.start();
t.join();
}
}
private final ScheduledExecutorService dispatcher = Executors.newSingleThreadScheduledExecutor();
private final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private final BlockingQueue<CustomEvent> q = new LinkedBlockingQueue<>(128);
@Override
public void run() {
for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) {
executor.submit(() -> {
while (!executor.isShutdown()) {
try {
var event = q.take();
event.run();
event.executor = Thread.currentThread();
event.end();
if (event.shouldCommit()) {
event.commit();
}
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
});
}
dispatcher.scheduleAtFixedRate(() -> {
var event = new CustomEvent();
event.dispatcher = Thread.currentThread();
event.begin();
if (event.isBlocking()) {
q.offer(event);
} else {
event.executor = Thread.currentThread();
event.run();
event.end();
if (event.shouldCommit()) {
event.commit();
}
}
}, 0, 5, TimeUnit.MILLISECONDS);
dispatcher.scheduleAtFixedRate(() -> {
var evt = new CollectionSizeEvent(q);
if (evt.shouldCommit()) {
evt.commit();
}
}, 0, 1, TimeUnit.SECONDS);
while (true) {
try {
System.out.print(". ");
Thread.sleep(1000);
} catch (InterruptedException ie) {
executor.shutdown();
dispatcher.shutdown();
break;
}
}
}
static long fib(long n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fib(n - 1) + fib(n - 2);
}
static class CustomEvent extends jdk.jfr.Event implements Runnable {
final String id = UUID.randomUUID().toString();
Thread dispatcher;
Thread executor;
final long idx = (long) (Math.random() * 46);
final boolean blocking = idx > 5;
long fib = 0;
boolean isBlocking() {
return blocking;
}
@Override
public void run() {
this.fib = fib(idx);
}
}
static class CollectionSizeEvent extends jdk.jfr.Event {
final int size;
CollectionSizeEvent(Collection<?> c) {
this.size = c.size();
}
}
}