我一直在研究2.4并且无法使程序正常工作而抛出空指针异常,因为它无法获取源和目标的帐号。现在我运行50个事务的程序,但是我使用的越多,空指针异常就出现了,如果你可以引导我走向正确的路径那将是很棒的。代码发布在下面。
以下是输出示例。
Withdrawing 592.5 from account 3
Balance is: 9339.92
Balance is: 9339.92
Withdrawing 496.81 from account 7
Withdrawing 233.86 from account 2
Balance is: 9339.92
Withdrawing 366.35 from account 5
Depositing 366.35 from account 6
Transfer occuring from 5 to 6 done.
Depositing 32.8 from account 6
Depositing 911.01 from account 8
Transfer occuring from 1 to 8
Withdrawing 601.23 from account 1
Depositing 601.23 from account 8
Transfer occuring from 1 to 8 done.
Withdrawing 115.42 from account 8
Transfer occuring from 8 to 5
Withdrawing 886.08 from account 8
Depositing 886.08 from account 5
Transfer occuring from 8 to 5 done.
Transfer occuring from 8 to 9
Withdrawing 820.83 from account 8
Transfer occuring from 5 to 7
Withdrawing 50.96 from account 5
Depositing 50.96 from account 7
Transfer occuring from 5 to 7 done.
Balance is: 8738.69
Exception in thread "Thread-43" Depositing 820.83 from account 9
Transfer occuring from 8 to 9 done.
[b]java.lang.NullPointerException
at OrderedTeller.transfer(OrderedTeller.java:54)
at OrderedTeller.run(OrderedTeller.java:29)[/b]
Withdrawing 361.35 from account 2
Depositing 472.04 from account 9
Balance is: 9452.789999999999
Transfer occuring from 1 to 2
Withdrawing 255.33 from account 1
Depositing 255.33 from account 2
Transfer occuring from 1 to 2 done.
Depositing 359.63 from account 2
Depositing 880.57 from account 6
Depositing 734.09 from account 7
Withdrawing 210.11 from account 4
Depositing 640.98 from account 5
Withdrawing 172.63 from account 5
代码:
public class Bank {
private List<BankAccount> bankAccounts = new ArrayList<BankAccount>();
public Bank() {
for (int i = 0; i < 10; i++) {
bankAccounts.add(new BankAccount(i, 10000.00));
}
doTransActions("Transactions.txt");
}
public void doTransActions(String fileName) {
BufferedReader in = null;
try {
String strLine = null;
in = new BufferedReader(new FileReader(fileName));
int distinationAccount = 0;
int sourceAccount = 0;
double amount = 0;
while ((strLine = in.readLine()) != null) {
java.lang.String[] tokens = strLine.split("[%]");
String transaction = tokens[0];
if (transaction.equals("TRANSFER")) {
sourceAccount = Integer.parseInt(tokens[1]);
distinationAccount = Integer.parseInt(tokens[2]);
amount = Double.parseDouble(tokens[3]);
BankAccount source = null;
BankAccount distination = null;
for (BankAccount account : bankAccounts) {
if (account.getNumber() == sourceAccount) {
source = account;
}
if (account.getNumber() == distinationAccount) {
distination = account;
}
}
new OrderedTeller(source, distination, transaction, amount).start();
} else {
sourceAccount = Integer.parseInt(tokens[1]);
amount = Double.parseDouble(tokens[2]);
BankAccount source = null;
for (BankAccount account : bankAccounts) {
if (account.getNumber() == sourceAccount) {
source = account;
}
}
new OrderedTeller(source, transaction, amount).start();
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
in.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
public class OrderedTeller extends Thread {
private BankAccount source = null, dest = null;
private String transType = null;
private double amount = 0;
public OrderedTeller(BankAccount a, BankAccount b, String transType, double amount)
{
source = a;
dest = b;
this.amount = amount;
this.transType = transType;
}
public OrderedTeller(BankAccount a, String transType, double amount)
{
source = a;
this.amount = amount;
this.transType = transType;
}
public void run() {
if (transType.equals("TRANSFER")) {
transfer(amount);
} else if (transType.equals("WITHDRAW")) {
source.withdraw(amount);
} else if (transType.equals("DEPOSIT")) {
source.deposit(amount);
} else if (transType.equals("BALANCE")) {
System.out.println("Balance is: "+source.getBalance());
} else {
System.out.println("ERROR: TRANSACTION TYPE NOT RECOGNIZED");
}
}
public void transfer(double amount) {
BankAccount first, second;
if (source.getNumber() < dest.getNumber()) {
first = source;
second = dest;
} else {
first = dest;
second = source;
}
synchronized (first) {
Thread.yield();
synchronized (second) {
System.out.println("Transfer occuring from " + source.getNumber() + " to " + dest.getNumber());
source.withdraw(amount);
dest.deposit(amount);
System.out.println("Transfer occuring from " + source.getNumber() + " to " + dest.getNumber()+ " done.");
}
}
}
}
public class BankAccount {
private double balance = 0;
private int number = 0;
public BankAccount(int number, double initialBalance) {
this.number = number;
balance = initialBalance;
}
public int getNumber() {
return number;
}
public double getBalance() {
return balance;
}
public synchronized void deposit(double amount) {
double prevBalance = balance;
System.out.println("Depositing " + amount + " from account " + number);
balance = prevBalance + amount;
}
public synchronized void withdraw(double amount) {
double prevBalance = balance;
System.out.println("Withdrawing " + amount + " from account " + number);
balance = prevBalance - amount;
}
}
这是我从中读取交易的文本文件 每行以真实文本文件中的事务开始。
TRANSFER%4%3%866.85
TRANSFER%2%7%861.79
BALANCE%9%895.41
DEPOSIT%7%475.82
WITHDRAW%3%845.92
WITHDRAW%4%766.69
BALANCE%10%591.67
DEPOSIT%8%12.22
TRANSFER%3%6%57.45
BALANCE%10%417.84
TRANSFER%10%8%928.33
TRANSFER%9%7%94.46
WITHDRAW%5%874.17
DEPOSIT%9%538.37
BALANCE%9%324.88
TRANSFER%6%7%773.23
DEPOSIT%3%81.81
BALANCE%8%564.51
TRANSFER%6%2%300.17
TRANSFER%5%6%366.35
DEPOSIT%10%627.87
DEPOSIT%8%911.01
TRANSFER%1%2%535.72
TRANSFER%1%8%601.23
TRANSFER%1%6%124.36
WITHDRAW%8%115.42
BALANCE%3%942.87
TRANSFER%8%5%886.08
DEPOSIT%7%604.41
WITHDRAW%2%361.35
WITHDRAW%2%233.86
WITHDRAW%4%210.11
DEPOSIT%6%32.8
DEPOSIT%6%880.57
WITHDRAW%7%496.81
WITHDRAW%5%172.63
BALANCE%1%70.4
DEPOSIT%7%734.09
BALANCE%1%274.6
DEPOSIT%5%640.98
WITHDRAW%3%592.5
DEPOSIT%9%472.04
BALANCE%1%647.71
TRANSFER%3%10%537.52
BALANCE%1%461.09
BALANCE%3%172.58
TRANSFER%8%9%820.83
TRANSFER%1%2%255.33
TRANSFER%5%7%50.96
DEPOSIT%2%359.63
答案 0 :(得分:3)
您的文件中的帐号似乎是从1开始的,而您生成的帐号则是零。因此,当它尝试在文件中执行涉及帐户#10的操作时,它将无法设置源或目标,并且您将获得空指针异常。
答案 1 :(得分:0)
如果我不得不猜测,我会说你在一个用错误的构造函数构造的OrderedTeller上调用run(),因为只有其中一个初始化了源和目标。为了简化事情。
如果不是这样,请尝试将某些内容粘贴到构造函数中,如果它使用null源和目标进行初始化,则抛出异常。这样您就可以找到问题实际来源的位置:错误地初始化对象。