简体   繁体   English

线程通信:wait()/ notifyAll()

[英]Thread communication: wait()/notifyAll()

I'm currently reading about Threads in Java and playing around with the wait() and notifyAll() methods. 我目前正在阅读有关Java中线程的知识 ,并使用了wait()notifyAll()方法。 I'm trying to understand this by coding a practical example, but I'm not getting the desired output. 我试图通过编写一个实际的例子来理解这一点,但是我没有得到想要的输出。

In short, following is an explanation of my code: The program simulates a simple work situation. 简而言之,以下是我的代码的解释:该程序模拟一个简单的工作情况。 That is, your balance starts at zero, and for each hour, is increased by 15 dollars (or some other currency). 也就是说,您的余额从零开始,并且每小时增加15美元(或其他某种货币)。 While the balance is under 100, the program should start working, until the balance surpasses that goal. 当余额低于100时,程序应开始工作,直到余额超过该目标为止。 Hence, the program should start working, counting the hours. 因此,该程序应开始工作,计算小时数。 Once the balance has reached/surpassed 100, you are done working, and the program should terminate. 一旦余额达到/超过100,您就可以完成工作,并且程序应终止。 The code consists of three classes, Shared (holding shared data and synchronized methods), Hours and Money , where the last two are subclasses of Thread. 该代码由三个类组成: Shared (持有共享数据和同步方法), HoursMoney ,其中最后两个是Thread的子类。

With this scenario in mind, the person should work for 7 hours, until having earned > 100 dollars. 考虑到这种情况,该人应该工作7个小时,直到收入> 100美元。

Code

class Shared {
    int hourSalary = 15;
    int numHours = 0;
    int balance;

/* Method handling balance checks */
public synchronized void earnMoney() {
    //As long as you have not earned 100 dollars
    while((numHours * 15) < 100) {
        try {
            wait(); //Wait for balance to increase
        }
        catch(InterruptedException e) {
            return;
        }
    }
    //balance += hourSalary;     //Increment by 15 after each hour
    balance = hourSalary * numHours;   //Incorrect, but stops the code at the right time!
    System.out.println("You have now worked " + numHours + " hours and increased your balance. Dollars earned so far " + balance);
    notifyAll();
}

/* Method handling work hours */
public synchronized void startWorking() {
    while(balance > 100) {
        try {
            wait();
        }
        catch(InterruptedException e) {
            return;
        }
    }
    numHours++;
    System.out.println("You have worked " + numHours + " hours and earned " + balance + " dollars.");
    notifyAll();
}

public synchronized boolean enoughMoney() {
    return balance > 100;   //Enough money when over 100 dollars
}
public synchronized boolean enoughWork() {
    return enoughMoney();   //Stop working when enough money
}
}

For the classes Hours and Money , the run()-methods are as follows: 对于小时金钱类,run()方法如下:

//run-method for the class Money
public void run() {
    while(!object.enoughMoney()) {
        object.earnMoney();
        try {
            sleep(1000);    // 1 second
        }
        catch(InterruptedException e) {
            return;
        }
    }//end while
}//end run

and

//run-method for the class Hours
public void run() {
    while(!object.enoughWork()) {
        object.startWorking();
        try {
            sleep(1000);    // 1 second
        }
        catch(InterruptedException e) {
            return;
        }
    }//end while
}//end run

Now, when running this code, the program terminates at the right moment, when having earned 105 dollars. 现在,当运行此代码时,该程序在获得105美元的正确时机终止。 However, the output provided at run time is incorrect. 但是,运行时提供的输出不正确。 It does not update the balance in accordance with the hours worked until the goal has been reached: 在达到目标之前,它不会根据工作时间来更新余额:

You have worked 1 hours and earned 0 dollars. 您工作了1个小时,赚了0美元。

You have worked 2 hours and earned 0 dollars. 您工作了2个小时,赚了0美元。

You have worked 3 hours and earned 0 dollars. 您工作了3个小时,赚了0美元。

You have worked 4 hours and earned 0 dollars. 您工作了4个小时,赚了0美元。

You have worked 5 hours and earned 0 dollars. 您工作了5个小时,赚了0美元。

You have worked 6 hours and earned 0 dollars. 您工作了6个小时,并赢得了0美元。

You have worked 7 hours and earned 0 dollars. 您工作了7个小时,并赢得了0美元。

You have now worked 7 hours and increased your balance. 您现在已经工作了7个小时,增加了余额。 Dollars earned so far 105 到目前为止获得的美元105

Any help/tips/tricks/etc. 任何帮助/提示/技巧/等。 on how to fix this is very much appreciated :) 关于如何解决这个问题非常感谢:)

I think I've found a solution to the problem. 我想我已经找到了解决问题的办法。 The issue had to to with running the threads. 问题必须与运行线程有关。 The startWorking()-method would not give up until it had reached the desired amount, and thus, the earnMoney()-method did not get proper access to the balance-variable, and thus printed out an incorrect value. startWorking()方法在达到所需数量之前不会放弃,因此,EarMoney()方法无法正确访问余额变量,因此打印出了错误的值。

However, if I simply modify the conditions in the while-loop for the methods: earnMoney() and startWorking() : 但是,如果我只是在while循环中为以下方法修改条件: earnMoney()startWorking ()

public synchronized void earnMoney() {
    //As long as you have not earned 100 dollars
    while(enoughMoney()) {
        try {
            wait(); //Wait for balance to increase
        }
        catch(InterruptedException e) {
            return;
        }
    }
    balance = hourSalary * getNumHours();     //Increment by 15 after each hour        
    setBalance(balance);

    System.out.println("You have now worked " + numHours + " hours and increased your balance. Dollars earned so far " + getBalance());
    notifyAll();
}

public synchronized void startWorking() {
    while(enoughWork()) {
        try {
            wait();
        }
        catch(InterruptedException e) {
            return;
        }
    }
    numHours++;
    System.out.println("You have worked " + numHours + " hours and earned " + getBalance() + " dollars.");
    notifyAll();
}

It seems to solve the problem. 看来解决了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM