Created
July 10, 2025 14:24
-
-
Save andsel/b56ba80e9bef1aaa95cf435f2366109b to your computer and use it in GitHub Desktop.
HdrHistogram Record usage in multithreaded context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ///usr/bin/env jbang "$0" "$@" ; exit $? | |
| //DEPS info.picocli:picocli:4.6.3 | |
| //DEPS org.hdrhistogram:HdrHistogram:2.2.2 | |
| import picocli.CommandLine; | |
| import picocli.CommandLine.Command; | |
| import picocli.CommandLine.Option; | |
| import picocli.CommandLine.Parameters; | |
| import java.security.SecureRandom; | |
| import java.time.Duration; | |
| import java.util.List; | |
| import java.util.ArrayList; | |
| import java.util.concurrent.Callable; | |
| import java.util.concurrent.CountDownLatch; | |
| import java.util.concurrent.TimeUnit; | |
| import java.util.function.Consumer; | |
| import org.HdrHistogram.Recorder; | |
| import org.HdrHistogram.Histogram; | |
| @Command(name = "hdrhistogram_cli", mixinStandardHelpOptions = true, version = "hdrhistogram_cli 0.1", | |
| description = "hdrhistogram_cli made with jbang") | |
| class hdrhistogram_cli implements Callable<Integer> { | |
| @Option(names = {"-t", "--threads"}, description = "Number of concurrent writer to the HDR recorder instance") | |
| private int numWriters; | |
| public static void main(String... args) { | |
| int exitCode = new CommandLine(new hdrhistogram_cli()).execute(args); | |
| System.exit(exitCode); | |
| } | |
| @Override | |
| public Integer call() throws Exception { | |
| System.out.println("HdrHistoragm test start"); | |
| SecureRandom random = new SecureRandom(); | |
| Recorder recorder = new Recorder(1_000_000, 2); | |
| if (numWriters == 0) { | |
| numWriters = 1; | |
| } | |
| CountDownLatch recordersFinished = new CountDownLatch(numWriters); | |
| List<Thread> writers = new ArrayList<>(); | |
| for (int j = 0; j < numWriters; j++) { | |
| Thread metricWriter = new Thread(() -> { | |
| metricRecroderLoop(recorder, random, recordersFinished); | |
| }); | |
| metricWriter.start(); | |
| writers.add(metricWriter); | |
| } | |
| Thread reporter = new Thread(() -> { | |
| Histogram intervalHistogram = recorder.getIntervalHistogram(); | |
| System.out.println("Estimation of histogram in bytes: " + intervalHistogram.getEstimatedFootprintInBytes()); | |
| printHistogram(intervalHistogram); | |
| try { | |
| System.out.println("thread | min | max | 50p | 90p |\n"); | |
| // till some recorder is around | |
| while (!recordersFinished.await(10, TimeUnit.MILLISECONDS)) { | |
| intervalHistogram.add(recorder.getIntervalHistogram()); | |
| printHistogram(intervalHistogram); | |
| } | |
| } catch (InterruptedException e) { | |
| //somebody interrupted, exit | |
| return; | |
| } | |
| }); | |
| reporter.setName("reporter"); | |
| reporter.start(); | |
| writers.stream().forEach(w -> joinInterruptable(w)); | |
| reporter.join(20_000); | |
| return 0; | |
| } | |
| private static void metricRecroderLoop(Recorder recorder, SecureRandom random, CountDownLatch recordersFinished) { | |
| try { | |
| for (int i = 0; i < 1_000_000; i++) { | |
| recorder.recordValue(random.nextInt(1_000_000)); | |
| Thread.sleep(Duration.ofNanos(1_000)); // 1 microsecond | |
| } | |
| recordersFinished.countDown(); | |
| } catch (InterruptedException e) { | |
| //somebody interrupted, exit | |
| return; | |
| } | |
| } | |
| private static void joinInterruptable(Thread w) { | |
| try { | |
| w.join(20_000); | |
| } catch (InterruptedException e) { | |
| //somebody interrupted, exit | |
| return; | |
| } | |
| } | |
| private static void printHistogram(Histogram intervalHistogram) { | |
| System.out.printf("%s | %d | %d | %d |%d |\n", | |
| Thread.currentThread().getName(), | |
| intervalHistogram.getMinValue(), | |
| intervalHistogram.getMaxValue(), | |
| intervalHistogram.getValueAtPercentile(50), | |
| intervalHistogram.getValueAtPercentile(90)); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment