java - 我正在创建一个多线程java应用程序,它模拟一个人的消费模式

标签 java multithreading timer simulation

/**
 *
 * 
 * A small class to handle deposits and withdrawls from a bank account
 * 
 */
package spendingsimulation;

//import java.util.Random;

public class BankAccount 
{
    public int accountBalance;
    public int incomeAmt;
    public BankAccount()
    {
        accountBalance = 0 ;
        //incomeAmt = 0;
    }

    public void deposit(int addAmount, String name)
    {
        // the 'name' argument holds the name of the source of this credit 

        accountBalance+=addAmount ;
        System.out.println(name + " added " + addAmount) ;
        System.out.println("Account balance is now standing at " + accountBalance);
    }

    public void withdraw(int takeAmount, String name)
    {
        // the 'name' argument holds the name of the bill being paid

        accountBalance-=takeAmount ;
        System.out.println(name + " took " + takeAmount) ;
        System.out.println("Account balance is now standing at " + accountBalance);
    }

    public int getBalance()
    {
        return accountBalance ;
    }

    //@Override
    /*public void run()
    {
        try
        {
            deposit(incomeAmt, incomeS1);
            getBalance();
            Thread.sleep(100) ;
        } // End of try block
        catch(InterruptedException ex)
        {
            System.out.println(typeOfUtility + " Terminated early") ;
        } // End of Catch clause

        System.out.println(typeOfUtility + " has finished") ;
    }  // End of method run()
    */


} // End of class BankAccount
<小时/>
package spendingsimulation;

import java.lang.Thread ;

public class SpendMain {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        System.out.println("Viewing expenditure");

        // Incoming payments
        Thread incomeS1 = new Thread(new Incomming("Wage Recieved", 2000, 1000) );
        Thread incomeS2 = new Thread(new Incomming("Interest Recieved", 10, 4000) );

        // Outgoing costs
        Thread outgoingS1 = new Thread(new Consumables("Oil Bill", 250, 3000)) ;
        Thread outgoingS2 = new Thread(new Consumables("Food Bill", 600, 1000)) ;
        Thread outgoingS3 = new Thread(new Consumables("Electricity Bill", 50, 1000)) ;
        Thread outgoingS4 = new Thread(new Consumables("Entertrainment Bill", 400, 1000)) ;
        Thread outgoingS5 = new Thread(new Consumables("Shopping Bill", 200, 1000)) ;

        System.out.println("Expenditure commencing") ;


        // Get the threads going
        //Incomming
        incomeS1.start();
        incomeS2.start();

        // Outgoing
        outgoingS1.start();
        outgoingS2.start();
        outgoingS3.start();
        outgoingS4.start();
        outgoingS5.start();


        System.out.println("Expenditure is now underway.") ; 


    }
}
<小时/>
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spendingsimulation;

import java.util.Random;

/**
 *
 * @author B00533474
 */
public class Incomming implements Runnable {

    //private int workingTime ;
   private String typeOfUtility ;
   // private Random randGen ;
    //private int incomingAmt;

    public Incomming(String name, int addAmount, int time){
        typeOfUtility = name ;

      //  randGen = new Random();
        //workingTime = randGen.nextInt(10000) ; // Up to 10 seconds

      //  outgoingAmt = amt;
    }

    //@Override
    public void run()
    {
        try
        {
            System.out.println(typeOfUtility + " has come into the account");
            System.out.println(" The balance on the account is now: ");
            //this.getBalance();
            Thread.sleep(1000) ;
        } // End of try block
        catch(InterruptedException ex)
        {
            System.out.println(typeOfUtility + " Terminated early") ;
        } // End of Catch clause

        System.out.println(typeOfUtility + " has finished") ;
    }  // End of method run()

}
<小时/>
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spendingsimulation;

import java.util.Random;
import java.util.Timer;

/**
 *
 * @author B00533474
 */
public class Consumables implements Runnable {

    private int workingTime ;
    private String typeOfUtility ;
    private Random randGen ;
    private int incomeAmt;


    Consumables(String name, int amt, int time) {
        typeOfUtility = name ;
        randGen = new Random();
        workingTime = randGen.nextInt(10000) ; // Up to 10 seconds
        incomeAmt = amt;
    }

    @Override
    public void run() {
        Timer myTimer = new Timer();

    }

}

我的问题是我不知道 run() 方法应该在多少个或哪个类中,以及如何正确访问和使用 Bank Account 类。我也不确定如何使用计时器类,我希望每一秒代表一周。任何帮助将非常感激。

最佳答案

这是一个简单的例子。

您有一个 Balance 类,其中包含一个作为当前余额的 AtomicInteger

您有三种可运行对象,收入支出报表 - 这些都是不言自明的。

该方法的核心是 main 方法。这使用 ScheduledExectorService 来安排不同的收入事件以不同的速率发生。评论解释了什么是什么。

最后,我们有一个任务会在一年后关闭整个系统 - 这可以很容易地更改或删除,在这种情况下它将永远运行。

您有按时间间隔重复执行任务和延迟后运行一次的任务(关闭任务)的示例。

此实现没有错误处理 - 任务将默默失败;但鉴于任务的简单性,不应该有任何理由让它们变得公平。

如果您想引入非整数值,您可能需要使用 BigDecimal,这会更复杂,因为您需要手动同步

static final class Balance {

    private final AtomicInteger balance;

    public Balance(int initalBalance) {
        this.balance = new AtomicInteger(initalBalance);
    }

    public void debit(final int amount) {
        balance.addAndGet(-amount);
    }

    public void credit(final int amount) {
        balance.addAndGet(amount);
    }

    public int balance() {
        return balance.get();
    }

    @Override
    public String toString() {
        return "£" + balance.get();
    }
}

static final class Income implements Runnable {

    private final Balance balance;
    private final int income;

    public Income(Balance balance, int income) {
        this.balance = balance;
        this.income = income;
    }

    @Override
    public void run() {
        balance.credit(income);
    }
}

static final class Expenditure implements Runnable {

    private final Balance balance;
    private final int cost;

    public Expenditure(Balance balance, int cost) {
        this.balance = balance;
        this.cost = cost;
    }

    @Override
    public void run() {
        balance.debit(cost);
    }
}

static final class Statement implements Runnable {

    private final Balance balance;

    public Statement(Balance balance) {
        this.balance = balance;
    }

    @Override
    public void run() {
        System.out.println("Your balance this month is " + balance.toString());
    }
}

public static void main(String[] args) throws ParseException {
    final Balance balance = new Balance(1000);
    final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
    //print balance  - monthly
    executorService.scheduleAtFixedRate(new Statement(balance), 0, 4, TimeUnit.SECONDS);
    //income - monthly
    executorService.scheduleAtFixedRate(new Income(balance, 1000), 0, 4, TimeUnit.SECONDS);
    //rent - monthly
    executorService.scheduleAtFixedRate(new Expenditure(balance, 500), 4, 4, TimeUnit.SECONDS);
    //food - weekly
    executorService.scheduleAtFixedRate(new Expenditure(balance, 50), 1, 1, TimeUnit.SECONDS);
    //shutdown after a year
    executorService.schedule(new Runnable() {
        @Override
        public void run() {
            executorService.shutdown();
        }
    }, 52, TimeUnit.SECONDS);

}

关于java - 我正在创建一个多线程java应用程序,它模拟一个人的消费模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16226231/

相关文章:

java - ModelMapper - 无法实例化目标实例

java - CXF、Camel 和 Spring 线程阻塞问题

c# - 将两种形式作为不同的线程运行(或至少 2 种形式运行 "parallel")

VB.net实时时间经过功能

java - 同一 Activity 中的 Intent - Android

java - 嵌套静态构建器类,对其管道的进一步解释

java - 如何将空格更改为下划线并使字符串不区分大小写?

c# - 如何创建一个将具有可以从另一个类读取的字段的线程

c# - 如何防止 C# System.Timers 计时器事件阻塞后续事件?

c# - asp.net 计时器和 response.redirect