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

Java 线程通信:wait()/notifyAll(),java,multithreading,wait,synchronized,notify,Java,Multithreading,Wait,Synchronized,Notify,我目前正在阅读Java中的线程,并使用wait()和notifyAll()方法。我试图通过编写一个实际的例子来理解这一点,但是我没有得到期望的输出 简而言之,下面是对我的代码的解释: 该程序模拟一个简单的工作情况。也就是说,您的余额从零开始,每小时增加15美元(或其他货币)。当余额低于100时,程序应开始工作,直到余额超过该目标。因此,程序应该开始工作,计算时间。一旦余额达到/超过100,您就完成了工作,程序应该终止。代码由三个类组成:共享(保存共享数据和同步方法)、小时和金钱,其中最后两个是线

我目前正在阅读Java中的线程,并使用wait()notifyAll()方法。我试图通过编写一个实际的例子来理解这一点,但是我没有得到期望的输出

简而言之,下面是对我的代码的解释: 该程序模拟一个简单的工作情况。也就是说,您的余额从零开始,每小时增加15美元(或其他货币)。当余额低于100时,程序应开始工作,直到余额超过该目标。因此,程序应该开始工作,计算时间。一旦余额达到/超过100,您就完成了工作,程序应该终止。代码由三个类组成:共享(保存共享数据和同步方法)、小时和金钱,其中最后两个是线程的子类

考虑到这种情况,员工应该工作7小时,直到收入超过100美元

代码

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
}
}

现在,当运行这段代码时,程序会在正确的时刻终止,那时已经赚了105美元。但是,运行时提供的输出不正确。在达到以下目标之前,它不会根据工作时间更新余额:

你工作了1个小时,赚了0美元

你工作了2个小时,赚了0美元

你工作了3个小时,赚了0美元

你工作了4个小时,赚了0美元

你工作了5个小时,赚了0美元

你工作了6个小时,赚了0美元

你工作了7个小时,赚了0美元

你现在已经工作了7个小时,增加了你的平衡。到目前为止赚了105美元


非常感谢您对如何解决此问题的任何帮助/提示/技巧/等等:)

我想我已经找到了解决此问题的方法。问题必须与运行线程有关。startWorking()方法在达到所需金额之前不会放弃,因此,earnMoney()方法无法正确访问balance变量,因此打印出了错误的值

但是,如果我只是修改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();
}
这似乎解决了问题

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