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

时间:2014-08-13 10:27:03

标签: java multithreading wait synchronized notify

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

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

考虑到这种情况,该人应该工作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
}
}

对于小时 Money 类,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

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

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

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

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

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

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

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

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

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

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

任何帮助/提示/技巧/等。关于如何解决这个问题非常感谢:)

1 个答案:

答案 0 :(得分:0)

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

但是,如果我只是修改方法的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();
}

似乎解决了这个问题。