onSpinWait Java 9

2

I'm porting a Java 8 to 9 application, I have some processes that use the Watchdog concept, which use something similar to:

public synchronized void run() {
    until = System.currentTimeMillis() + watchdogParam.getTimeout();
    while (!cancelado) {
        long delta = until - System.currentTimeMillis();
        try {
            if (delta > 0) {
                wait(delta);
            } else {
                wait();
            }
            if (!cancelado && until <= System.currentTimeMillis()) {
                fazAlgo();
            }
        } catch (InterruptedException ex) { }
    }
}

Reading the Thread documentation, I saw that a new method has been made available: onSpinWait , where an API note says that the call of this method should be placed where there is looping (in the context of Thread ), but also says not to use it is correct.

That's right, I'd like to know what you need to use this method and whether or not it's really necessary to use it.

    
asked by anonymous 24.10.2017 / 19:15

1 answer

2

This method Thread.onSpinWait() serves to that a thread tells the JVM that it is in a busy waiting process. That is, it signals that the thread is within a loop waiting for something to happen, and although it is not sleeping or blocked, it is also not making progress on the work it intends to do. Therefore, this method informs the JVM that it can perform some sort of performance optimization in this situation.

The Javadoc example exemplifies the case well:

class EventHandler {
    volatile boolean eventNotificationNotReceived;
    void waitForEventAndHandleIt() {
        while ( eventNotificationNotReceived ) {
            java.lang.Thread.onSpinWait();
        }
        readAndProcessEvent();
    }

    void readAndProcessEvent() {
        // Read event from some source and process it
         . . .
    }
}

Note that in this code it stays within a while expecting the variable to change to false . The variable has the volatile modifier, so it is possible that the value of it changes suddenly when it is changed by another thread. However, as long as it stays as true , the thread will be consuming CPU uselessly, that is, at the same time that the thread is busy (because it is consuming CPU, not sleeping and not blocked), it is also waiting for something to happen - that's busy waiting.

This method is something of a very specific and casuistic purpose, being used for tuning and very specific micro-optimizations. It is something that is very easy to be used in an inappropriate way and very difficult to be used properly. Also, the JVM in question can bypass this method altogether, and implement it by simply doing nothing.

I see a certain relationship with System.gc() and Thread.yield() . All three serve to warn the JVM that a particular optimization may be appropriate, but the JVM may choose to ignore it completely and it is also something that should have no impact on the behavior or functionality of the program, just performance. And the three also have a strong propensity to be misused.

    
24.10.2017 / 19:58