I was studying about AutomaticInteger. It stated that the use of an AtomicInteger makes an integer operation non-blocking. It is said that the compareAndSet() method of the AtomicInteger makes use of Compare-and-set feature. Compare-and-set feature returns false if it is not successful. To make Compare-and-set successful, compareAndSet() method of the AtomicInteger has to use it in an infinite loop. It is said that since the integer operations are small, it is more beneficial to wait in the loop than to switch the context.
To my understanding, every thread has a fixed time quanta available. If a thread cannot complete its work in its time quanta, it will have to be preempted. Then it will get a chance again later.
So my questions are:
After being unable to gain a lock on the Synchronized method or block, is any thread preempted before its time quanta expire? If yes, when does that thread get CPU time again?
That's up to the scheduler. But if the thread gets pre-empted, it's only because there are other threads that can make immediate forward progress.
How is a kind of spinlock (infinite loop) present in compareAndSet() method of AtomicInteger class able to reduce the context switch time?
It will only loop if the AtomicInteger
was modified, in which case that means another thread made forward progress. Two threads can't make forward progress by modifying the very same shared resource at the very same time anyway. If it loops a lot, that means lots of forward progress is being made by other threads. In realistic conditions, it would be extraordinary rare for a thread to spin more than twice and that's still going to be cheaper than an unnecessary context switch.