Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is fast, wait notify or busy wait in Java?

I understand that use of busy-wait is not a good programming practice and preferably synchronized object (wait-notify) should be used whenever possible. But I would like to know if one is ready to sacrifice cpu cycles, then will busy wait be faster or wait-notify ?

I assume that wait-notify will involve an intrinsic lock over synchronized object and also signal might come from kernel to wake-up the thread, making this approach much slower than a busy-wait, where one could just check a condition continuously till it is satisfied. As soon as this condition is satisfied (e.g. boolean value == true), thread could come out of busy wait. As per my understanding, I feel busy-wait should be faster.

I would appreciate if others can share their thoughts and correct me if my argument is wrong.

like image 694
Sachin Avatar asked Jul 25 '14 05:07

Sachin


People also ask

What is a busy wait Java?

Busy waiting occurs when a thread, while waiting for some condition to change, executes a loop instead of giving up the CPU. Because busy waiting is wasteful of CPU time, we should modify the algorithm.

What is difference between wait and notify in Java?

The wait() method causes the current thread to wait until another thread invokes the notify() or notifyAll() methods for that object. The notify() method wakes up a single thread that is waiting on that object's monitor. The notifyAll() method wakes up all threads that are waiting on that object's monitor.

What is notify and notifyAll in Java?

Notification. In case of multiThreading notify() method sends the notification to only one thread among the multiple waiting threads which are waiting for lock. While notifyAll() methods in the same context sends the notification to all waiting threads instead of single one thread.

What is notify in Java?

The notify() method is defined in the Object class, which is Java's top-level class. It's used to wake up only one thread that's waiting for an object, and that thread then begins execution. The thread class notify() method is used to wake up a single thread.

What is the difference between wait () and sleep () method?

Wait() method releases lock during Synchronization. Sleep() method does not release the lock on object during Synchronization. Wait() should be called only from Synchronized context. There is no need to call sleep() from Synchronized context.

What does wait () do in Java?

wait() causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).


1 Answers

Experimentation suggests that you will see the flag sooner if you busy wait than if you wait and notify (on my hardware, anyway). (Details below.) The difference is very very very very very small and so this would only be applicable to very rare apps. Stock trading apps, for instance, where companies are after any advantage they can get (vying to locate their servers as near the exchange as possible to get microsecond improvements in their network feeds from the exchange and such) might consider the difference worth it. I can imagine some science applications as well.

In the vast majority of apps, the difference will be in effect no difference at all.

But what happens to the CPU is, of course, that one of the cores hard-pegs:

hardpeg

That's bad in terms of impacting other processes on the box and in terms of power consumption in the data center.

So: Use with extreme reluctance, only in situations where it really matters.


Data (very small sample, but the code follows):

Busy Wait:       10631  12350  15278
Wait and Notify: 87299 120964 107204
Delta:           76668 108614  91926

Times are in nanoseconds. Billionths of a second. The average delta above is 92403ns (0.092402667 milliseconds, 0.000092403 seconds).

BusyWait.java:

public class BusyWait {

    private static class Shared {
        public long setAt;
        public long seenAt;
        public volatile boolean flag = false;
    }

    public static void main(String[] args) {
        final Shared shared = new Shared();
        Thread notifier = new Thread(new Runnable() {
            public void run() {
                System.out.println("Running");
                try {
                    Thread.sleep(500);
                    System.out.println("Setting flag");
                    shared.setAt = System.nanoTime();
                    shared.flag = true;
                }
                catch (Exception e) {
                }
            }
        });
        notifier.start();
        while (!shared.flag) {
        }
        shared.seenAt = System.nanoTime();
        System.out.println("Delay between set and seen: " + (shared.seenAt - shared.setAt));
    }
}

WaitAndNotify.java:

public class WaitAndNotify {

    private static class Shared {
        public long setAt;
        public long seenAt;
        public boolean flag = false;
    }

    public static void main(String[] args) {
        (new WaitAndNotify()).test();
    }
    private void test() {
        final Shared shared = new Shared();
        final WaitAndNotify instance = this;
        Thread notifier = new Thread(new Runnable() {
            public void run() {
                System.out.println("Running");
                try {
                    Thread.sleep(500);
                    System.out.println("Setting flag");
                    shared.setAt = System.nanoTime();
                    shared.flag = true;
                    synchronized (instance) {
                        instance.notify();
                    }
                }
                catch (Exception e) {
                }
            }
        });
        notifier.start();
        while (!shared.flag) {
            try {
                synchronized (this) {
                    wait();
                }
            }
            catch (InterruptedException ie) {
            }
        }
        shared.seenAt = System.nanoTime();
        System.out.println("Delay between set and seen: " + (shared.seenAt - shared.setAt));
    }
}
like image 96
T.J. Crowder Avatar answered Oct 07 '22 13:10

T.J. Crowder