Precise timing event dispatching in Java I have coded a tool to produce precise timing events in Java. You set a value in BPM, and you receive events in your listener at the most precise timing it possibly can be with Java.
It is basic. A thread, a loop, read the bpm value, invokes the listener (lambda), compute the time to sleep to match the bpm requested, and go on.
To achieve high precision, I sleep a bit less than calculated, and then have a noop loop that does the fine grain waiting.
It works well enough for my needs (less than 0.01BPM of error more than 95% of the time), but I was curious on how I could enhance it. Specificaly :

reduce the cpu usage
reduce the memory footprint
any coding that may permit to reduce the tolerance of the unit tests (see MAX_ERRORS_RATE_ALLOWED and BPM_TOLERANCE) without generating assertion errors
more or less any comment that is relevant to the context

The full project (maven) with very few dependencies is here: https://github.com/sebpiller/metronom
Here is the loop doing the computation:
    // https://github.com/sebpiller/metronom/blob/develop/src/main/java/ch/sebpiller/tictac/TicTac.java
    private void loopUntilStopped() {
        long n;
        int i=0;
        while (!stopped) {
            // ok, then tick and wait exactly the correct amount of time
            n = System.nanoTime(); // memorize last boom

            ///// Notify of tick
            ticTacListener.beat(i++ % 4 != 0, bpm);

            // next loop bpm
            bpm = bpmSource.getBpm();

            if (bpm &lt;= 0) {
                // shutdown as soon as the bpm return 0
                stopped = true;
            } else {
                // compute next tick nanos:
                long nanosBetweenTicks = (long) (60_000_000_000d / bpm);

                /// How much time did we need to sleep until next boom
                long sleepNanos = n + nanosBetweenTicks - System.nanoTime() - __JAVA_CORRECTION_NANOS;

                if (sleepNanos &lt; 0) {
                    LOG.warn(&quot;missed tic! ({}ns)&quot;, sleepNanos);
                    i++; // erf... let's hope we miss only one tick
                } else {
                    sleepInterrupted(sleepNanos / 1_000_000, (int) (sleepNanos % 1_000_000));

                    /* Just in  case this lady was really early this time...
                       fine tuning of the slept time: just loop doing nothing until we are close from the goal */
                    // this is where all the precision is really obtained... this wonderful, but empty loop !
                    while(System.nanoTime()&lt;n + nanosBetweenTicks) /* no body here! */;
                }
            }
        }

A parameterized unit test checks the precision of the implementation here, and run the test with various tempo: https://github.com/sebpiller/metronom/blob/develop/src/test/java/ch/sebpiller/tictac/TicTacTest.java (the test should take about 10 minutes to complete in his current form)
Bonus: any specific advice regarding the execution of this code on an ARM32v7 board (RPi4)
Thank you in advance !
First of all, let me clarify that you can't do precise timing on a &quot;normal&quot; desktop or server operating system. You can be close, but the schedulers are not designed for that, you're not guaranteed to get a time slice for execution at all. The smaller your time-slices get, the bigger the error margins will be. The higher the load on the machine will be, the more slices you will miss.

 * Like my girlfriend, Java has some problems to be on time. He is always a bite late.

I'm most likely old and grumpy, but &quot;funny&quot; comments and variable names are a waste of everyones time at the end of the day. That and, if you ever want to use your code as portfolio for a job, or in your job, might cost you. Because when I see that comment, I can deduct a few things:

The programmer considers it okay to make fun of others in the public.
The programmer does not know anything about how the JVM works.
The programmer does not know anything about how the OS scheduler works.
The programmer does most likely not know anything about the Java ecosystem (Java is used for high-speed trading with stock exchanges, doing trades in the microsecond range).

Of course, what you do in your private projects is none of my business, but be aware that this comes at a cost in one way or another...and maybe not for you, as others might have to maintain your code at some point.
And to ask a different question...does your girlfriend know she's a cheap joke on the internet for you?

long n;
int i=0;

These names could be better, a lot better actually.

long nanosBetweenTicks = (long) (60_000_000_000d / bpm);

This would, do well as a constant.

__JAVA_CORRECTION_NANOS

Normally, you don't have leading underscores under the Java convention.

i++; // erf... let's hope we miss only one tick

That is what I was talking about earlier and is a very good example for a completely unhelpful comment. It tells me that the programmer either had no idea what they were doing, or did not care enough to check it.

while(System.nanoTime()&lt;n + nanosBetweenTicks) /* no body here! */;

I believe that this will not be optimized away because of the System.nanoTime() function call, but I would not bet on it.

The code is otherwise well formatted, and most of the names are good. I'm not sure about the rest of the logic, it seems oddly complicated for what you describe.