理解wait()和notify()的必要性

fre*_*233 7 java multithreading

我试图通过使用wait()和notify()访问共享资源或依赖其状态来理解实现线程的必​​要性.

我看到的想法是监视对象并等待它们的可用性并在使用后释放它们以使它们可用于其他线程/方法,但为什么这些方法是必要的而不是仅仅将相关对象声明为静态volatile以便其他线程在不调用这些方法的情况下了解状态的变化?

例如

在一家餐厅,有2名厨师.其中一位厨师是一位优秀的厨师(更好的烹饪品质,......)并带有布尔值isGoodCook = true,而第二位厨师则是一名厨师并带有布尔值isGoodCook = false.

一个厨师只有一次可以做饭的设备.糟糕的厨师会在特定的时间内做饭(=烹饪时间),而优秀的厨师偶尔会来厨房来接管糟糕的厨师做饭的任务.这位优秀的厨师在他的烹饪过程中永远不会被打断,并且一旦开始他就会为他的整个烹饪时间做饭.

(坏厨师停止烹饪,只要好厨师做饭的一部分(=烹饪时间的好厨师)).

在好厨师停止做饭之后,坏厨师必须再次进行准备饭菜的任务.

private boolean cooking; //is equipment used at the moment
private boolean isGoodCook;
private boolean cookingDesire; //indicating to chef to stop cooking
private int cookingTime;


public CookingTask(boolean isGoodCook, int cookingTime)
{
    this.isGoodCook = isGoodCook;
    this.cookingTime = cookingTime;
}

public void run()
{  
    if(isGoodCook)
    {
        //notify actual cook to stop cooking
        cookingDesire = true; 
    }
    //wait til equipment to cook
    //is available
    while(cooking)
    {
        try 
        {
            wait();
        } catch (InterruptedException e) 
        {
            e.printStackTrace();
        }
    }
    //reserve equipment
    cooking = true;
    cookingDesire = false;
    //notify other threads (= bad cook)
    notifyAll();
    startCooking();
}

private void startCooking()
{
    for(int i = 0; i < cookingTime; cookingTime--)
    {
        try 
        {
            Thread.sleep(1000);
            //if good chef comes in
            if(cookingDesire)
            {
                //bad chef starts to pause
                startBreak();
            }
        }
        catch (InterruptedException e) 
        {
            e.printStackTrace();
        }
    }
    cooking = false;
}

public void startBreak()
{
    //bad chef stops cooking
    cooking = false;
    notifyAll();
    //measure break time of bad chef
    long stopCookingTime = System.currentTimeMillis();
    while(cookingTime > 0 && cooking)
    {
        try 
        {
            wait();
        } catch (InterruptedException e) 
        {
            e.printStackTrace();
        }
    }
    int pausedTime = toIntExact((System.currentTimeMillis() - stopCookingTime)/1000);
    //calculate remaining cookingTime
    cookingTime -= pausedTime;
    cooking = true;
    notifyAll();
}
Run Code Online (Sandbox Code Playgroud)

也许有人通过阅读并很快勾勒监测我的误解/时间wait()和notify()多线程的,我会很高兴地欣赏它!

Gho*_*ica 4

静态意味着类的所有对象共享该数据。您认为如何使用静态字段来表示有关特定线程对象状态的任何信息?

我想人们可以摆脱等待/通知;在某种程度上,一个线程必须查询其他线程的属性。但这意味着“活动”:“等待”线程必须进行轮询。当然,您不能不断轮询,因此您可能希望它休眠一段时间。这几乎和等待一样,但更复杂,因为您必须通过编写代码来管理所有微妙的细节。

通过等待/通知,您就有了推送模型。如果一个线程需要等待;你告诉它这样做;然后,当时间到了,它就会被唤醒。这是一个非常清晰、直接的语义。

因此,当您提出不同的模型来解决该问题时;你确实必须证明你的模型达到了同样的目标;除此之外,请考虑该模型的其他好处。