Using Busy Spinning as Wait Strategy in Java
Last Updated :
02 Nov, 2022
Busy Spinning is a wait strategy in which one thread waits for some condition to happen which is to be set by some other thread. Here the waiting thread loops continuously without releasing the CPU cycles. This leads to bad performance as the CPU cycles are wasted by a waiting thread.
A classic use case that fits this strategy very naturally is the producer-consumer problem. The producer thread adds items to a queue. The consumer thread waits until an item is produced by the producer before consuming items from the queue. The consumer thread while waiting holds the CPU cycles and thus there is wastage of CPU resources which can be used for some other processing by other threads.
Another example to better understand this strategy is to consider a customer ordering pizza from a Pizza counter. After placing an order, the customer keeps asking the person at the counter if his order is ready every 5 seconds. Here, the customer waiting for this order can utilize his time doing other activities like talking to his friends, browsing the latest news, and so on, instead of busy spinning on the status check of his pizza order.
Example
Java
// Java Program to illustrate Busy Spinning as Wait
// Strategy
// Importing input output classes
import java.io.*;
// Importing List class from java.util package
import java.util.List;
// Class 1
// Helper class
public class Pizza {
private String base;
public String getBase() { return base; }
public void setBase(String base) { this.base = base; }
public List<String> getToppings() { return toppings; }
public void setToppings(List<String> toppings)
{
this.toppings = toppings;
}
private List<String> toppings;
public Pizza(String base, List<String> toppings)
{
super();
this.base = base;
this.toppings = toppings;
}
public void make()
{
System.out.println("Making pizza");
}
}
// Class 2
// Helper class
public class Customer implements Runnable {
PizzaMaker pizzaMaker;
public Customer(PizzaMaker pizzaMaker)
{
this.pizzaMaker = pizzaMaker;
}
public void run()
{
while (this.pizzaMaker.isInProgress) {
System.out.println(
Thread.currentThread().getName()
+ ":-Pizza order complete??");
System.out.println("--Busy Spinning---");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(
"Received the ordered pizza:-"
+ Thread.currentThread().getName());
System.out.println("Base of the pizza is : "
+ pizzaMaker.pizza.getBase());
System.out.println(
"Toppings are : "
+ pizzaMaker.pizza.getToppings());
}
}
// Class 3
// Helper class
public class PizzaMaker implements Runnable {
Pizza pizza;
boolean isInProgress;
public PizzaMaker(Pizza pizza)
{
this.pizza = pizza;
this.isInProgress = true;
}
public void run()
{
System.out.println("Pizza order in progress");
pizza.make();
try {
Thread.sleep(3000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(
" Making of pizza with base :"
+ this.pizza.getBase() + " and toppings as "
+ this.pizza.getToppings() + " is complete :- "
+ Thread.currentThread().getName());
this.isInProgress = false;
}
}
// Class 4
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
//
String base = "thick crust base";
// Creating a List of String type
List<String> toppings = new ArrayList<>();
// Adding elements to the object
toppings.add("tomato");
toppings.add("corn");
toppings.add("cheese");
toppings.add("olive");
Pizza pizza = new Pizza(base, toppings);
PizzaMaker pizzaMaker = new PizzaMaker(pizza);
Customer customer = new Customer(pizzaMaker);
Thread pizzaMakerThread
= new Thread(pizzaMaker, "pizzaMakerThread");
Thread customerThread
= new Thread(customer, "customerThread");
pizzaMakerThread.start();
customerThread.start();
}
}
Output:
Pizza order in progress
Making pizza
customerThread:-Pizza order complete??
--Busy Spinning---
customerThread:-Pizza order complete??
--Busy Spinning---
customerThread:-Pizza order complete??
--Busy Spinning---
Making of pizza with base :thick crust base and toppings as [tomato, corn, cheese, olive] is complete :- pizzaMakerThread
Received the ordered pizza:-customerThread
Base of the pizza is : thick crust base
Toppings are : [tomato, corn, cheese, olive]
Output explanation:
In this example, we have 2 classes that implement the Runnable interface. When the PizzaMaker constructor is invoked, it sets the boolean variable isInProgress as true, which means that it has received the pizza order and making of pizza is in progress. In run() it invokes the pizza's make(). Once pizza is made, it sets the isInProgress boolean variable to false. The Customer thread does a busy spin by looping continuously inside the while loop checking for the status of the order through the boolean variable isInProgress. When the PizzaMaker class sets this variable to false, the customer thread continues with further processing. A better approach would be to implement the wait, notify, and notifyAll() methods from the Object class. The thread waiting for a condition to be satisfied will release CPU resources and perform some other tasks. When some other thread sets this condition for which the thread was waiting, it notifies the waiting thread through notify() method.
Similar Reads
Understanding execute async script in Selenium Using java
Understanding executeAsyncScript in Selenium Using Java is crucial for handling asynchronous JavaScript operations during test automation. The executeAsyncScript method allows Selenium to wait for certain operations, like AJAX calls or timeouts, to complete before proceeding. This is particularly us
2 min read
Producer-Consumer Solution using Threads in Java
In computing, the producer-consumer problem (also known as the bounded-buffer problem) is a classic example of a multi-process synchronization problem. The problem describes two processes, the producer and the consumer, which share a common, fixed-size buffer used as a queue. The producer's job is t
6 min read
Banking Transaction System using Java
In order to understand one must have a strong grasp over Java OOPs, Java Multithreading & Java Interrupted-Exception. If not go through them as the title in itself is a sheer implementation of multithreading. Approaches: Rookie approachMultithreading approachSynchronization invoking in multithre
12 min read
LinkedBlockingDeque in Java with Examples
The LinkedBlockingDeque class in Java is a part of the Java Collection Framework. It was introduced in JDK 1.6 and it belongs to java.util.concurrent package. It is a Deque(Doubly Ended Queue) which blocks a thread if that thread tries to take elements out of it while the Deque is empty. It implemen
14 min read
ReentrantReadWriteLock Class in Java
ReentrantReadWriteLock class of Java is an implementation of ReadWriteLock, that also supports ReentrantLock functionality. The ReadWriteLock is a pair of associated locks, one for read-only operations and one for writing. Whereas, the ReentrantLock is a re-entrant mutual exclusion Lock with the sam
5 min read
Killing threads in Java
A thread is automatically destroyed when the run() method has completed. But it might be required to kill/stop a thread before it has completed its life cycle. Previously, methods suspend(), resume() and stop() were used to manage the execution of threads. But these methods were deprecated by Java 2
7 min read
TimeUnit sleep() method in Java with Examples
The sleep() method of TimeUnit Class is used to performs a Thread.sleep using this time unit. This is a convenience method that sleeps time arguments into the form required by the Thread.sleep method. Syntax: public void sleep(long timeout) throws InterruptedException Parameters: This method accepts
2 min read
Parallelizing Tasks in Java using ForkJoinPool
In the realm of concurrent programming, Java's ForkJoinPool stands out as a powerful framework for parallelizing tasks. It is particularly adept at handling computationally intensive applications, leveraging the capabilities of modern multi-core processors. This article will delve into the intricaci
6 min read
PriorityBlockingQueue Class in Java
The PriorityBlockingQueue class is part of the java.util.concurrent package and implements a thread-safe, priority-based blocking queue. It is similar to the PriorityQueue, but it supports operations for blocking threads, such as take() and put() which are not available in PriorityQueue.Thread-safe
9 min read
Lifecycle and States of a Thread in Java
A thread in Java can exist in any one of the following states at any given time. A thread lies only in one of the shown states at any instant:New StateRunnable StateBlocked StateWaiting StateTimed Waiting StateTerminated StateThe diagram below represents various states of a thread at any instant:Lif
5 min read