我有下面的java代码。这给出了不同的输出在每个。我想我必须使用信号量和互斥量,但我不知道该在哪里使用。我对多线程很陌生,所以有人能告诉我这个程序中的线程在哪里。我该怎么做才能得到一致的结果
Account.java
package banking;
public class Account {
final String accountHolder;
final String accountType;
double balance=0;
public Account(String name, String type,double credit) {
this.accountHolder = name;
this.accountType = type;
this.balance=credit;
}
public void deposit(double credit) {
balance += credit;
}
public void withdraw(double credit) {
balance -= credit;
}
public void addinterest(double rate) {
balance *= (100+rate)/100.0;
}
}Banking.java
package banking;
public class Banking {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("Application started");
Account savings = new Account("Pete","Super Saver",1000);
Account checking = new Account("Pete","Free Checking",1000);
System.out.println("\nBeginning of month");
System.out.println(savings.accountType + ":\t"+ savings.balance);
System.out.println(checking.accountType + ":\t"+ checking.balance);
System.out.println("Total before \t"+ (checking.balance+savings.balance));
Interest checkInterest = new Interest(checking, -10);
Interest saveInterest = new Interest(savings, 10);
Transfer transfer = new Transfer(savings,checking,100);
checkInterest.start();
saveInterest.start();
transfer.start();
Thread.sleep(520);
System.out.println("\nEnd of month");
System.out.println(savings.accountType + ":\t"+ savings.balance);
System.out.println(checking.accountType + ":\t"+ checking.balance);
System.out.println("Total after \t"+ (checking.balance+savings.balance));
System.out.println("Main thread finished");
}
}Interest.java
package banking;
import java.util.logging.Level;
import java.util.logging.Logger;
class Interest extends java.lang.Thread {
final Account myAccount;
double myRate;
public Interest(Account account, double rate) {
this.myAccount=account;
this.myRate = rate;
setName("Interest");
}
@Override
public void run() {
System.out.println("Interest this month on "+ myAccount.accountType + ":\t" + myAccount.balance*myRate/100.0);
myAccount.addinterest(myRate);
//System.out.println(getName() + " to account " + myAccount.accountType + " successfully applied");
}
}Transfer.java
package banking;
import java.util.logging.Level;
import java.util.logging.Logger;
class Transfer extends java.lang.Thread {
final Account myAccount1;
Account myAccount2;
double myAmount;
public Transfer(Account account1,Account account2, double amount) {
this.myAccount1=account1;
this.myAccount2=account2;
this.myAmount = amount;
setName("Transfer");
}
@Override
public void run() {
myAccount1.withdraw(myAmount);
myAccount2.deposit(myAmount);
System.out.println(getName() + " from " + myAccount1.accountType + " to " + myAccount2.accountType + " successfully applied");
}
}请帮我解决这个问题。
发布于 2016-05-19 23:13:39
不需要信号量。只需在synchronized类中的每个方法之前添加Account。例如:
public synchronized void deposit(double credit) {
balance += credit;
}编辑
当一个方法是synchronized时,运行时环境保证如果多个线程在给定对象中调用相同的方法,那么它们中只有一个会执行,而其他线程则会等待它完成。然后执行另一个线程,以此类推。
EDIT2
另外,不要直接访问Account的数据成员。使它们成为private,并定义synchronized getter和setter。您的程序中真正的问题在于传输操作:
myAccount1.withdraw(myAmount);
myAccount2.deposit(myAmount);从这种角度来说,它不是原子的。例如,假设兴趣线程在执行中在这两行之前执行,在它们之间执行另一行。你会得到不同的最终结果。要解决这个问题,请向Account类添加以下方法:
public synchronized void transfer (Account to, double amount) {
this.withdraw (amount);
to.deposit(amount);
}并将这两行替换为:
synchronized(myAccount2) {
myAccount1.transfer(myAccount2, myAmount);
}在调用synchronized方法时添加transfer块的原因是,为了执行传输,需要获取两个对象的两个锁。synchronized(myAccount2)获得myAccount2的锁,而transfer的调用获得myAccount1的锁,因为方法transfer是同步的。
EDIT3
在您的程序中也存在一个概念问题。你在计算两个帐户的利息,并在它们之间转账,所有这些都是并行的。所以,如果你先转移钱,然后计算利息,或者你先计算利息,然后再转帐,就会有不同的结果。试着用手算一下。如果您想对操作进行排序,不要使用线程,只需按顺序调用方法
发布于 2016-05-21 23:43:13
您可以将thread.join()用于checkInterest和saveInterest。所以当这两件事结束时,转移就开始了。
checkInterest.start();
saveInterest.start();
checkInterest.join();
saveInterest.join();
transfer.start();https://stackoverflow.com/questions/37335462
复制相似问题