Uso de Busy Spinning como estrategia de espera en Java

Busy Spinning es una estrategia de espera en la que un subproceso espera que ocurra alguna condición que otro subproceso debe establecer. Aquí, el subproceso en espera se repite continuamente sin liberar los ciclos de la CPU. Esto conduce a un mal rendimiento ya que los ciclos de la CPU se desperdician por un subproceso en espera.

Un caso de uso clásico que se ajusta a esta estrategia de forma muy natural es el problema productor-consumidor. El subproceso productor agrega elementos a una cola. El subproceso del consumidor espera hasta que el productor produzca un elemento antes de consumir elementos de la cola. El subproceso del consumidor mientras espera retiene los ciclos de la CPU y, por lo tanto, hay un desperdicio de recursos de la CPU que otros subprocesos pueden utilizar para algún otro procesamiento.

Otro ejemplo para comprender mejor esta estrategia es considerar un cliente que pide pizza en un mostrador de pizza. Después de realizar un pedido, el cliente sigue preguntando a la persona en el mostrador si su pedido está listo cada 5 segundos. Aquí, el cliente que espera este pedido puede utilizar su tiempo para realizar otras actividades, como hablar con sus amigos, consultar las últimas noticias, etc., en lugar de estar ocupado comprobando el estado de su pedido de pizza.

Ejemplo

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();
    }
}

Producción:

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]

Explicación de salida:

En este ejemplo, tenemos 2 clases que implementan la interfaz Runnable. Cuando se invoca el constructor de PizzaMaker , establece la variable booleana isInProgress como verdadera, lo que significa que ha recibido el pedido de pizza y la elaboración de la pizza está en curso. En run() invoca el make() de la pizza. Una vez que se hace la pizza, establece la variable booleana isInProgress en falso. el clientethread hace un giro ocupado al hacer un bucle continuamente dentro del bucle while verificando el estado del pedido a través de la variable booleana isInProgress. Cuando la clase PizzaMaker establece esta variable en falso, el subproceso del cliente continúa con el procesamiento adicional. Un mejor enfoque sería implementar los métodos de esperar, notificar y notificarTodos() de la clase Objeto. El subproceso que espera que se cumpla una condición liberará recursos de la CPU y realizará otras tareas. Cuando algún otro subproceso establece esta condición por la que el subproceso estaba esperando, notifica al subproceso en espera a través del método de notificación().

Publicación traducida automáticamente

Artículo escrito por suchitrasrinivas y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *