BankAccount问题和线程,请帮忙

时间:2011-02-16 06:55:16

标签: java multithreading

我一直在研究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

2 个答案:

答案 0 :(得分:3)

您的文件中的帐号似乎是从1开始的,而您生成的帐号则是零。因此,当它尝试在文件中执行涉及帐户#10的操作时,它将无法设置源或目标,并且您将获得空指针异常。

答案 1 :(得分:0)

如果我不得不猜测,我会说你在一个用错误的构造函数构造的OrderedTeller上调用run(),因为只有其中一个初始化了源和目标。为了简化事情。

如果不是这样,请尝试将某些内容粘贴到构造函数中,如果它使用null源和目标进行初始化,则抛出异常。这样您就可以找到问题实际来源的位置:错误地初始化对象。