📜  在Java使用忙旋转作为等待策略

📅  最后修改于: 2022-05-13 01:54:58.743000             🧑  作者: Mango

在Java使用忙旋转作为等待策略

Busy Spinning 是一种等待策略,其中一个线程等待某个条件发生,该条件将由其他某个线程设置。这里等待线程不断循环而不释放 CPU 周期。这会导致性能不佳,因为等待线程浪费了 CPU 周期。

一个非常自然地适合这种策略的经典用例是生产者-消费者问题。生产者线程将项目添加到队列中。在从队列中消费项目之前,消费者线程会一直等待,直到生产者生产了一个项目。等待时的消费者线程持有 CPU 周期,因此会浪费 CPU 资源,这些资源可用于其他线程的其他处理。

更好地理解此策略的另一个示例是 考虑一位顾客从比萨柜台订购比萨。下订单后,客户每 5 秒就会不断询问柜台人员是否准备好订单。在这里,等待该订单的顾客可以利用他的时间做其他活动,例如与他的朋友交谈、浏览最新消息等,而不是忙于检查他的披萨订单的状态。

例子

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 getToppings() { return toppings; }
  
    public void setToppings(List toppings)
    {
        this.toppings = toppings;
    }
  
    private List toppings;
  
    public Pizza(String base, List 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 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();
    }
}


输出:

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]

输出说明:

在这个例子中,我们有 2 个实现 Runnable 接口的类。当调用PizzaMaker构造函数时,它会将布尔变量 isInProgress 设置为 true,这意味着它已收到披萨订单并且正在制作披萨。在 run() 中,它调用了比萨饼的 make()。制作披萨后,它将 isInProgress 布尔变量设置为 false。客户线程通过在 while 循环内通过布尔变量 isInProgress 检查订单状态来不断循环来进行繁忙的旋转。当 PizzaMaker 类将此变量设置为 false 时,客户线程将继续进行进一步处理。更好的方法是实现 Object 类中的 wait、notify 和 notifyAll() 方法。等待条件满足的线程将释放 CPU 资源并执行一些其他任务。当某个其他线程设置该线程正在等待的条件时,它会通过 notify() 方法通知正在等待的线程。