【问题标题】:I am tasked with creating a Java application that used 2 synchronized threads to calculate monthly interest and update the account balance我的任务是创建一个 Java 应用程序,该应用程序使用 2 个同步线程来计算每月利息并更新帐户余额
【发布时间】:2019-11-14 14:38:30
【问题描述】:

这是代码参考的参数。 创建一个类 AccountSavings。该类有两个实例变量:一个保持年利率的双变量和一个保持储蓄平衡的双变量。年利率为 5.3,储蓄余额为 100 美元。
• 创建计算每月利息的方法。 • 创建一个运行两个线程的方法。使用匿名类来创建这些线程。第一个线程调用每月利息计算方法12次,然后显示储蓄余额(第12个月的余额)。之后,该线程休眠 5 秒。第二个线程调用每月利息计算方法12次,然后显示储蓄余额(第12个月的余额)。在主线程结束之前,这两个线程必须完成。 • 将您的主要方法添加到同一个类中并测试您的线程。这两个线程执行后,储蓄余额必须保持不变

在我的 runThread 方法中调用monthlyInterest 方法时出现错误。 不能从静态上下文引用非静态方法monthlyInterest() 我似乎无法弄清楚如何解决这个问题。

...

import static java.lang.Thread.sleep;

class AccountSavings {

double annualInterest=5.3;
double savings=100.00;



public void monthlyInterest(){
double monthlyRate;
monthlyRate = annualInterest/12;
double balance = 0;
balance+=savings*monthlyRate;
}

public synchronized static void runThread(){

    Thread t1;
    t1 = new Thread(){
        AccountSavings accountSavings= new AccountSavings();
        @Override
        public void run(){
            for(int i=1;i<13;i++){
                System.out.println("Balance after " + i + "month: " + monthlyInterest());
            }
            try{sleep(5000);}
            catch(InterruptedException e){e.printStackTrace();}
        }
    };
Thread t2= new Thread(){

AccountSavings accountSavings=new AccountSavings();
@Override
public void run(){

    for(int i=1;i<13;i++){
    System.out.println("Balance after " + i + " month: " + monthlyInterest(balance));
    }
    try{sleep(5000);}
    catch(InterruptedException e){e.printStackTrace();}    
}
};
t1.start();
t2.start();

}

public static void main(String[] args){

    runThread();

}

}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    编辑

    从 AccountSavings 对象调用方法怎么样? accountSavings.montlyInterest()

    class AccountSavings {
    
       private double annualInterest = 5.3;
       private double balance = 0;
    
       public void monthlyInterest() {
          double monthlyRate = annualInterest / 12;
          double savings = 100.00;
          balance += savings * monthlyRate;
       }
    
       public static void runThread() {
    
          Thread t1;
          t1 = new Thread() {
             AccountSavings accountSavings = new AccountSavings();
             @Override
             public void run() {
                int i=1;
                for (; i < 13; i++) {
                   accountSavings.monthlyInterest();
                }
                System.out.println("Balance Thread 1 after " + (i-1) + " month: " + accountSavings.balance);
                try {
                   sleep(5000);
                } catch (InterruptedException e) {
                   // failed to sleep
                }
             }
          };
          Thread t2 = new Thread() {
    
             @Override
             public void run() {
                AccountSavings accountSavings = new AccountSavings();
                int i=1;
                for (; i < 13; i++) {
                   accountSavings.monthlyInterest();
                }
                System.out.println("Balance Thread 2 after " + (i-1) + " month: " + accountSavings.balance);
                try {
                   sleep(5000);
                } catch (InterruptedException e) {
                  // failed to sleep
                }
             }
          };
          t1.start();
          t2.start();
       }
    
       public static void main(String[] args) {
          runThread();
       }
    }
    
    1. 12 个月后的平衡线程 1:530.0000000000001
    2. 12 个月后的平衡线程 2:530.0000000000001

    【讨论】:

      【解决方案2】:

      首先,关键字synchronized 必须指向执行临界区的方法,而不是创建线程的方法。所以在这种情况下,它必须转到 monthlyInterest。现在,您正在创建两个 AccountSavings,它们仅由一个线程修改,因此无需添加 synchronized 关键字,除非您希望由多个线程修改它。另外,我建议使用 Java 8 lambda 语法来创建线程,这样更简单、更易于阅读。最后,您的代码将类似于下面的代码。

      账户储蓄

      public class AccountSavings {
      
          private double annualInterest;
          private double savings;
          private double balance;
      
          public synchronized double monthlyInterest() {
              double monthlyRate;
              monthlyRate = annualInterest / 12;
              balance += savings * monthlyRate;
              return balance;
          }
      
          AccountSavings(double annualInterest, double savings, double balance) {
              this.annualInterest = annualInterest;
              this.savings = savings;
              this.balance = balance;
          }
      
      }
      

      主要

      public class Main {
      
          public static void main(String args[]) {
      
              Thread t1 = new Thread(() -> {
                  AccountSavings accountSavings = new AccountSavings(5.3, 100, 0);
                  for (int i = 1; i < 13; i++) {
                      System.out.println("Balance after " + i + "month: " + accountSavings.monthlyInterest() + " | Thread 1");
                  }
                  try {
                      sleep(5000);
                  } catch (Exception e) {
                      System.out.println("Error sleeping");
                  }
              });
      
              Thread t2 = new Thread(() -> {
                  AccountSavings accountSavings = new AccountSavings(5.3, 100, 0);
                  for (int i = 1; i < 13; i++) {
                      System.out.println("Balance after " + i + "month: " + accountSavings.monthlyInterest() + " | Thread 2");
                  }
                  try {
                      sleep(5000);
                  } catch (InterruptedException e) {
                      System.out.println("Error sleeping");
                  }
              });
              t1.start();
              t2.start();
      
          }
      
      }
      

      【讨论】:

      • 感谢您提供的信息,在与我的教授交谈后,她特别要求我们创建一个方法来运行线程,然后在 main 方法中调用该方法。所以我现在的问题是,我是保留 runThread 方法并在 main 中调用它,还是有比我目前所做的更有效的方法来做到这一点?
      • 在主类中调用runThread 是可以的。真的没有太多选择。您可以按照自己的方式进行操作,即调用静态方法或创建新类。我想说静态方法更适合这个练习。
      猜你喜欢
      • 1970-01-01
      • 2011-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-04
      • 1970-01-01
      相关资源
      最近更新 更多