Java 多线程银行模拟
目前我正在玩java中的多线程,我不确定这是如何工作的。。我觉得我在互联网上看到的一个简单例子中理解了这一点,但不知何故,我无法理解这在我从互联网上找到并修改的银行模拟应用程序中是如何工作的 以下是我所拥有的: 人员类别:Java 多线程银行模拟,java,multithreading,java-threads,Java,Multithreading,Java Threads,目前我正在玩java中的多线程,我不确定这是如何工作的。。我觉得我在互联网上看到的一个简单例子中理解了这一点,但不知何故,我无法理解这在我从互联网上找到并修改的银行模拟应用程序中是如何工作的 以下是我所拥有的: 人员类别: package threadsproject; public class Person { private String name; public Person(String name){ this.name = name; }
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();
}
}
package-threads项目;
导入java.util.Scanner;
公共类BankThread扩展线程实现可运行{
私人p;
公共银行线程(p人){
这个,p=p;
}
公开募捐{
对于(int i=0;i<3;i++){
试一试{
Account acc=Account.getAcc(p);
扫描仪s=新的扫描仪(System.in);
System.out.println(“输入存款金额:”);
int dep=s.nextInt();
会计存款(dep);
试一试{
睡眠(500);
}catch(InterruptedException ex){}
System.out.println(“输入取款金额:”);
int with=s.nextInt();
如果(使用>Account.getBal()){
System.out.println(“你没有足够的资金。”);
}否则{
acc.撤回(带);
}
System.out.println(“最终余额:+Account.getBal());
}捕获(例外e){
e、 printStackTrace();
}
}
}
公共静态void main(字符串[]args)引发InterruptedException{
//TODO自动生成的方法存根
人员p1=新人员(“人员1”);
人员p2=新人员(“人员2”);
人员p3=新人员(“人员3”);
银行线程bt1=新银行线程(p1);
bt1.start();
bt1.join();
银行线程bt2=新银行线程(p2);
bt2.start();
bt2.join();
银行线程bt3=新银行线程(p3);
bt3.start();
bt3.join();
}
}
正如我提到的,这是我发现并修改的一个例子。这是可行的,但我认为不正确。在threads类中,for循环为每个线程执行代码3次。
另一个问题是,每个线程的帐户余额保持不变。因此,如果我的第一个线程有100个最终余额,那么第二个线程也会以100个余额开始,而不是从0开始。
如果我有不同的对象,它应该从0开始,对吗
这是一个截图
您描述的场景反映了帐户类中
静态
成员字段的用法。关键字static
意味着字段不再是对象边界,因为它们是类边界。因此,帐户
对象的每个实例在其任何实例上都有相同的静态
字段
要修复它,您必须删除静态字段
public static int balance;
public static Account acc;
private static Person p;
首先,正如评论中提到的,Account类的名称是错误的。静态字段表示此字段依赖于类,而不是依赖于对象(类的实例)。所以,您将在整个应用程序中共享这些静态字段,这对于多线程来说是一个很好的例子 For循环对每个线程执行三次,因为它意味着
for (int i = 0; i < 3; i++) {
for(int i=0;i<3;i++){
它将在i=0、i=1和i=2时调用
如果您想使用共享资源进行多线程处理,在本例中,我给您的建议是将Account类的名称更改为FamilyAccount,将Person更改为FamilyMember,并将其视为家庭成员的共享帐户。拥有一个帐户将具有更多逻辑,然后您可以使用多线程处理并进行检查例如,如果每个成员都看到实际金额
如果你删除静态字段,我认为在多线程的情况下没有意义。如果每个人都有一个帐户,并且他们作为一个线程工作,那么就没有必要进行同步
另外,您的Account类是一个奇怪的单例,其中有公共构造函数和getAcc方法,它们总是返回类的相同实例
我鼓励您查看和阅读有关交易和单身的信息,以便更好地理解案例。不知道您在哪里找到了
帐户类,但请扔掉您找到的书籍或网站链接,因为这是垃圾。您有一个Person
类,具有良好的非静态字段,因此您可以创建多个person
对象。但是你有一个帐户
类,包含所有静态
字段,这意味着你的系统中只能有一个帐户。银行最多只有一个帐户有什么用?完全滥用了静态
。烧掉它!!!谢谢你,我现在已经修复了它。你在这个例子中看到的帐户是仍然被视为独生子女,我不确定这是否一定能解决问题