【问题标题】:Multi Threading banking simulation多线程银行模拟
【发布时间】:2017-01-04 09:34:55
【问题描述】:

此时我正在使用 java 中的多线程,我不确定它是如何工作的。我觉得我在互联网上看到的一个简单示例中理解了这一点,但不知何故我不能了解这是如何在我从互联网上找到并修改的银行模拟应用程序中工作的。

这是我所拥有的:

人物类:

package threadsproject;

public class Person {

    private String name;

    public Person(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

账户类:

package threadsproject;

public class Account {

    public static int balance;
    public static Account acc;
    private static Person p;

    public static int getBal(){
        return balance;
    }

    public void setBal(int bal){
        Account.balance = bal;
    }

    public static Account getAcc(Person p){
        if(acc == null){
            acc = new Account();
        }
        Account.p = p;
        return acc;

    }

    public synchronized void deposit(int val){
        try{

            if(val > 0){
                System.out.println("Person "+p.getName()+" is making a deposit.");
                try{
                    Thread.sleep(500);
                }catch(Exception e){}
                balance = balance + val;
                System.out.println("Person "+p.getName()+" completed the deposit.");
            }else{
                System.out.println("Can't deposit.");
            }
            System.out.println("Person "+p.getName()+" deposited "+val);

        }catch(Exception e){}
    }

    public synchronized void withdraw(int val){
        try{

            if(balance >= val){
                System.out.println("Person "+p.getName()+" is making a withdraw.");
                try{
                    Thread.sleep(500);
                }catch(Exception e){}
                balance = balance - val;
                System.out.println("Person "+p.getName()+" completed the withdraw.");
            }else{
                System.out.println("Can't withdraw.");
            }
            System.out.println("Person "+p.getName()+" withdrew "+val);

        }catch(Exception e){}
    }

}

线程类:

package threadsproject;

import java.util.Scanner;

public class BankThread extends Thread implements Runnable{

    private Person p;

    public BankThread(Person p){
        this.p = p;
    }

    public void run(){
        for (int i = 0; i < 3; i++) {
            try {
                Account acc = Account.getAcc(p);
                Scanner s = new Scanner(System.in);
                System.out.println("Enter deposit ammount:");
                int dep = s.nextInt();
                acc.deposit(dep);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) { }

                System.out.println("Enter withdrawal ammount:");
                int with = s.nextInt();
                if(with > Account.getBal()){
                    System.out.println("You don't have enough funds.");
                }else{
                    acc.withdraw(with);
                }
                System.out.println("Final balance: "+Account.getBal());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub

        Person p1 = new Person("Person1");
        Person p2 = new Person("Person2");
        Person p3 = new Person("Person3");
        BankThread bt1 = new BankThread(p1);
        bt1.start();
        bt1.join();
        BankThread bt2 = new BankThread(p2);
        bt2.start();
        bt2.join();
        BankThread bt3 = new BankThread(p3);
        bt3.start();
        bt3.join();
    }

}

正如我所提到的,这是我找到并修改的一个示例。这有效,但我认为不正确。在线程类中,for 循环为每个线程执行 3 次代码。 我遇到的另一个问题是每个线程的帐户余额保持不变。因此,如果我的第一个线程有 100 个最终余额,那么第二个线程开始时相同,余额为 100,而不是从 0。 如果我有不同的对象,应该从 0 开始吧?

这是截图。

【问题讨论】:

  • 不知道你在哪里找到了Account 课程,但是把你找到的书或网站链接扔掉,因为它是垃圾。您有一个具有良好非静态字段的 Person 类,因此您可以为您的银行创建多个 Person 对象。但是你有一个Account 类,其中包含所有static 字段,这意味着你的系统中只能有一个Account。一家最多只有一个账户的银行有什么好处?完全滥用static。烧掉!!!

标签: java multithreading java-threads


【解决方案1】:

您描述的场景反映了 Account 类中 static 成员字段的用法。关键字static 表示字段不再受对象限制,因为它们是受类限制的。因此,Account 对象的每个实例都将在它的任何实例上具有相同的 static 字段。

要修复它,您必须删除静态字段

 public static int balance;
 public static Account acc;
 private static Person p;

【讨论】:

  • 您在此示例中看到帐户仍被视为单例,我不确定这是否能解决问题
【解决方案2】:

首先,正如 cmets 中提到的,它是 Account 类的错误名称。静态字段意味着该字段依赖于类,而不是依赖于对象(类的实例)。因此,您将在应用程序之间共享这些静态字段,这可能是多线程的一个很好的例子。

每个线程执行 3 次 For 循环,因为它的本意是

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

它将在 i=0、i=1 和 i=2 时调用

如果您想使用共享资源使用多线程,我建议您将 Account 类的名称更改为 FamilyAccount,将 Person 更改为 FamilyMember,并将其视为家庭成员的共享帐户。拥有一个帐户将具有更多逻辑,然后您可以使用多线程并检查例如每个成员是否看到实际金额。

如果您要删除静态字段,我认为在多线程的情况下它没有任何意义。如果每个人都有一个帐户,并且他们作为一个线程工作,则无需同步。

此外,您的 Account 类是 Singleton 的奇怪案例,其中有公共构造函数和 getAcc 方法,它们总是返回相同的类实例。

我鼓励您查看和阅读有关事务和 Singleton 的信息,以更好地理解案例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-09
    • 1970-01-01
    • 2014-06-20
    相关资源
    最近更新 更多