gpt4 book ai didi

Java锁定条件等待并通知: IllegalMonitorStateException

转载 作者:行者123 更新时间:2023-11-30 02:55:00 25 4
gpt4 key购买 nike

我是 Java 新手。我刚刚读了《java核心》这本书。我遇到了有关“条件和锁定”的问题。

我从书上敲了一段代码到eclipse中做了一些练习。

当我运行代码时,“sufficientFund.wait();”行抛出 IllegalMonitorStateException。为什么这里有异常(exception)?

我在谷歌上搜索了一段时间,我知道“这个方法只能由作为该对象监视器所有者的线程调用。”我认为当前线程拥有锁,因为 'bankLock.lock();'在 wait() 之前执行。我认为代码的正确行为是,当前线程应该卡在sufficientFund.wait()处,但事实并非如此。

package com.first.java;

import java.util.Scanner;
import java.util.concurrent.locks.*;

public class BankTranf {

private static final int NACCOUNT = 3;
public static final double INITAL_BALANCE = 1000;

public static void main(String[] args) {

Bank bank = new Bank(NACCOUNT, INITAL_BALANCE);

for (int i = 0; i < NACCOUNT; i++) {

TransferRunnable transferRunnable = new TransferRunnable(bank, i, INITAL_BALANCE);

Thread thread = new Thread(transferRunnable);
thread.start();
}

System.out.println("press any key to exit.");
Scanner in = new Scanner(System.in);
in.nextLine();
System.exit(0);
}

}

class Bank {
private final double[] account;
private Lock bankLock;
private Condition sufficientFund;

public Bank(int n, double initialBanlance) {
account = new double[n];
for (int i = 0; i < account.length; i++) {
account[i] = initialBanlance;
}

bankLock = new ReentrantLock();
sufficientFund = bankLock.newCondition();

}

public void transfer(int from, int to, double amount) {
bankLock.lock();

try {
while (account[from] < amount) {
System.out.println(Thread.currentThread().getName() + " does'nt hava enough money");
sufficientFund.wait();
}

System.out.println(Thread.currentThread());

account[from] -= amount;
System.out.printf("%10.2f from %d to %d ", amount, from, to);
account[to] += amount;
System.out.printf(" Total balance: %10.2f%n", getTotalBalance());
sufficientFund.signalAll();

} catch (Exception ex) {
ex.printStackTrace();
} finally {
bankLock.unlock();
}
}

public double getTotalBalance() {
double d = 0;
bankLock.lock();
try {
for (double n : account) {
d += n;
}
return d;
} finally {
bankLock.unlock();
}
}

public int size() {
return account.length;
}

}

class TransferRunnable implements Runnable {

private Bank bank;
private int fromAccount;
private double maxAmount;
private int DELAY = 10;

public TransferRunnable(Bank b, int from, double max) {
bank = b;
this.fromAccount = from;
this.maxAmount = max;
}

@Override
public void run() {

try {
while (true) {
int toAcount = (int) (bank.size() * Math.random());
double amount = maxAmount * Math.random();
bank.transfer(fromAccount, toAcount, amount);
Thread.sleep(4000/* (int)(DELAY*Math.random()) */);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

我还尝试了另一种方法,我删除了所有的锁定和条件,而不是使用“同步”,代码按我的预期运行。

public synchronized void transfer(int from, int to, double amount) {
//bankLock.lock();

try {
while (account[from] < amount) {
System.out.println(Thread.currentThread().getName() + " does'nt hava enough money");

wait();
}

System.out.println(Thread.currentThread());

account[from] -= amount;
System.out.printf("%10.2f from %d to %d ", amount, from, to);
account[to] += amount;
System.out.printf(" Total balance: %10.2f%n", getTotalBalance());

notifyAll();

} catch (Exception ex) {
ex.printStackTrace();
} finally {

}
}

public synchronized double getTotalBalance() {
double d = 0;

try {
for (double n : account) {
d += n;
}
return d;
} finally {

}
}

最佳答案

请注意,Condition 因为 Java 中的任何类都扩展了 Object,因此它具有从 Object 继承的 wait 方法>,我相信您在这里错误地调用了它,您打算调用等待条件的方法是 Condition#await 而不是 wait

关于Java锁定条件等待并通知: IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37508189/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com