Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Using Busy Spinning as Wait Strategy in Java

  • Last Updated : 08 May, 2021

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.

Attention reader! Don’t stop learning now. Get hold of all the important Java Foundation and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

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(
            "Topings 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
Topings 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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!