onSpinWait​() method of Thread class - Java 9

前端 未结 4 569
傲寒
傲寒 2021-02-05 01:59

While learning Java 9 features I came across a new method of Thread class, called onSpinWait​. As per javadocs, this method is used for this:

4条回答
  •  醉梦人生
    2021-02-05 02:27

    For a real-world example, say you wanted to implement asynchronous logging, where threads that want to log something, don't want to wait for their log message to get "published" (say written to a file), just so long as it eventually does (because they've got real work to do.)

    Producer(s):
    concurrentQueue.push("Log my message")
    

    And say, you decide on having a dedicated consumer thread, that is solely responsible for actually writing log messages to a file:

    (Single)Consumer
    
    while (concurrentQueue.isEmpty())
    {
        //what should I do?
    
    }
    writeToFile(concurrentQueue.popHead());
    //loop
    

    The issue is what to do in inside the while block? Java has not provided ideal solutions: you could do a Thread.sleep(), but for how long and that's heavyweight; or a Thread.yield(), but that's unspecified, or you could use a lock or mutex*, but that's often too heavyweight and slows the producers down as well (and vitiates the stated purpose of asynchronous logging).

    What you really want is to say to the runtime, "I anticipate that I won't be waiting too long, but I'd like to minimize any overhead in waiting/negative effects on other threads". That's where Thread.onSpinWait() comes in.

    As a response above indicated, on platforms that support it (like x86), onSpinWait() gets intrinsified into a PAUSE instruction, which will give you the benefits that you want. So:

    (Single)Consumer
    
    while (concurrentQueue.isEmpty())
    {
        Thread.onSpinWait();
    
    }
    writeToFile(concurrentQueue.popHead());
    //loop
    

    It's been shown empirically that this can improve latency of "busy-waiting" style loops.

    I also want to clarify, that it is not just useful in implementing "spin-locks" (although it's definitely useful in such a circumstance); the code above does not require a lock (spin or otherwise) of any kind.

    If you want to get into the weeds, you can't do better than Intel's specs

    *For clarity, the JVM is incredibly smart in attempting to minimize the cost of mutexes, and will use lightweight locks initially, but that's another discussion.

提交回复
热议问题