欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多线程编程之理财 博客分类: 线程 java多线程理财生产者消费者 

程序员文章站 2024-03-24 20:33:40
...

      现实生活中,我们一边工作,一边消费,正常情况下会把多余的钱存起来,比如存到余额宝,还可以多挣点钱,现在就有这个情况:我每月可以发工资20000万元 (暂定每月的1号),每月消费5000(租房+生活费)元(暂定每月的1号),其中租金是大头占90%,交房租的方式可以选择(一月一交,两月一交、三月一交),理财:1万元存余额宝一天可以赚1元钱,想知道半年后的理财情况,选择哪种交房租的方式更省钱,具体省多少?

问题分析:这个问题属于于生产者—消费者模型,其中生产者—发工资+理财,消费者—交房租+生活费,其中银行账户作为储存容器,只不过这里跟普通的生产者—消费者模型不一样的是生产者和消费者的动作是指定的,因为日期是定下来的,那来吧直接动手实现吧!

 

  

package pc.d3;

import java.util.Calendar;
import java.util.Date;

import util.DateUtils;

/**
 * 日期对象
 */
public class DateConstant {
	
	/**开始日期,默认是从2015-7-1开始 **/
	private static Date nowDate = DateUtils.parseDate("2015-7-1");  

	public static Date getNowDate() {
		return nowDate;
	}
	
	public static String getNowDateForString(){
		return DateUtils.formatTimestamp(getNowDate());
	}
	
	/**
	 * 表针走动
	 */
	public static void timeRun(){
		nowDate = DateUtils.addSecond(nowDate, 10);
	}
	
	public static boolean isEnd(){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(nowDate);
		
		//判断是否2015年12月31日
		if(calendar.get(Calendar.YEAR)==2016){
			return true;
		}
		return false;
	}
}

 

   

package pc.d3;

import org.apache.log4j.Logger;

/**
 * 银行账户
 */
public class Account {
	
	Logger logger = Logger.getLogger(Producer.class);   
	
	/**账户金额,默认是0元 **/
	private float allMoney = 0; 
	
	public float getMoney(){
	   return allMoney;	
	}
	/**
	 * 消费
	 * @param money
	 */
	public boolean subMoney(float money){
		if(money==0){
			logger.info(DateConstant.getNowDateForString()+"取钱:银行账户没有钱,好穷啊");
			return false;
		}
		float sourceMoney = allMoney;
		allMoney = allMoney - money;
		logger.info(DateConstant.getNowDateForString()+"取钱:"+sourceMoney+"-"+money+"="+allMoney);
		return true;
	}
	
	/**
	 * 存钱
	 */
	public boolean addMoney(float money){
		if(DateConstant.isEnd()){//结束了
			logger.info("-------已结束!-------");
			return false;
		}
		float sourceMoney = allMoney;
		allMoney = allMoney + money;
		logger.info(DateConstant.getNowDateForString()+"存钱:"+sourceMoney+"+"+money+"="+allMoney);
		return true;
	}
}

  

   

package pc.d3;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;


/**
 * 生产者---往银行账户加钱(主要来自工作的薪水、理财赚的钱)
 * 其中:1)薪水每月18000元
 *     2)理财日收益率: 1/10000 (即1万元一天收益1元)
 * @author zhoufy
 */
public class Producer implements Runnable{

	Logger logger = Logger.getLogger(Producer.class);        
	  
	/**发工资记录**/
	private Set<String> recordPaySet = new HashSet<String>();
	private String yearMonth = "";
	/**利息结算记录**/
	private Set<String> recordInterestSet = new HashSet<String>();
	private String yearMonthDay = "";
	/**银行账户**/
	private Account account;
	
	/**
	 * 构造子函数
	 */
	public Producer(Account a){
		account = a;
	}
	
	/**
	 * 是否发工资时间(以每月的1号12点为准发工资)
	 * @return
	 */
	public boolean isPayOffTime(){
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(DateConstant.getNowDate());
		
		//先判断是否本月已经发过工资
		yearMonth = calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH);
		if(recordPaySet.contains(yearMonth)){
			return false;
		}
		
		//判断是否发工资时间
		if(calendar.get(Calendar.DAY_OF_MONTH) == 1 && calendar.get(Calendar.HOUR_OF_DAY) == 12){
			logger.info("-----------发工资时间: " + DateConstant.getNowDateForString());
			return true;
		}
		return false;
	}
	
	/**
	 * 是否利息结算时间(以每天的18点结算)
	 * @return
	 */
	public boolean isInterestCountTime(){
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(DateConstant.getNowDate());
		
		//先判断是否今天已经结算过利息
		yearMonthDay = calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH) + calendar.get(Calendar.DAY_OF_MONTH);
		if(recordInterestSet.contains(yearMonthDay)){
			return false;
		}
		//logger.info("--->"+calendar.get(Calendar.HOUR_OF_DAY));
		//判断是否利息结算时间
		if(calendar.get(Calendar.HOUR_OF_DAY) == 18){
			//logger.info("利息结算时间: " + DateConstant.getNowDateForString());
			return true;
		}
		return false;
	}
	@Override
	public void run() {
		while(!DateConstant.isEnd()){ //如果还没有结束
			if(isPayOffTime()){
				//如果到了发工资时间
				if(account.addMoney(18000)){
					recordPaySet.add(yearMonth);
				}
			}
			
			if(isInterestCountTime()){
				//如果到了利息结算时间
				if(account.addMoney((float)(account.getMoney()*0.0001))){
					recordInterestSet.add(yearMonthDay);
				}
			}
			
			DateConstant.timeRun();
			
			logger.error("当前时间:" + DateConstant.getNowDateForString());
		}
		
		logger.info("账户共有:" + account.getMoney() + "元");
	}

}

 

  

package pc.d3;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;

import org.apache.log4j.Logger;

/**
 * 消费者---交房租、生活费等开销每个月5000元
 * @author zhoufy
 */
public class Consumer implements Runnable{

	Logger logger = Logger.getLogger(Consumer.class);   
	
	/**交房租记录**/
	private Set<String> recordChummageSet = new HashSet<String>();
	private String yearMonth = "";
	/**银行账户**/
	private Account account;
	/**房租N月一交**/
	private int splitMonth = 3;
	/**上一次交房租月份**/
	private int lastPayMonth = 0;
	
	/**
	 * 构造子函数
	 */
	public Consumer(Account a){
		account = a;
	}
	
	/**
	 * 是否消费时间(以每月的1号12点为交房租)
	 * @return
	 */
	public boolean isPayOffTime(){
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(DateConstant.getNowDate());
		
		if(lastPayMonth==0){
			lastPayMonth = calendar.get(Calendar.MONTH) - splitMonth;
		}
		
		//先判断是否已经交过房租
		yearMonth = calendar.get(Calendar.YEAR) + "-" + calendar.get(Calendar.MONTH);
		if(recordChummageSet.contains(yearMonth)){
			return false;
		}
		
		//判断是否交房租时间
		if(calendar.get(Calendar.MONTH)==(lastPayMonth+splitMonth) && calendar.get(Calendar.DAY_OF_MONTH) == 1 && calendar.get(Calendar.HOUR_OF_DAY) == 13){
			logger.info("交房租时间: " + DateConstant.getNowDateForString());
			lastPayMonth = calendar.get(Calendar.MONTH);
			return true;
		}
		return false;
	}
	
	@Override
	public void run() {
		while(!DateConstant.isEnd()){ //如果还没有结束
			if(isPayOffTime()){
				//如果到了交房租时间
				if(account.subMoney(5000*splitMonth)){ //注意:这里是交房租金额=月房租数*一次性交的月数
					recordChummageSet.add(yearMonth);
				}
			}
		}
	}

}

 

package pc.d3;

public class Main {

	public static void main(String[] args) {
		
		/**创建银行账户**/
		Account account = new Account();
		
		/**生产者**/
		new Thread(new Producer(account)).start();
		
		/**消费者**/
		new Thread(new Consumer(account)).start();
	}

}

 

    

 

    运行结果:
        房租一个月一交,最后账户金额为:78841.414元
        房租二个月一交,最后账户金额为:78795.43元
        房租三个月一交,最后账户金额为:78747.89元


     哎,看来还是一月一交省钱,可天下又有几个房东好心让租房者一个月一交房租呢!
    我有一个梦想,愿有一天,中华儿女不再因租房而奔波劳碌!


     说明:其中运行结果不是一次运行出来的,是分三次运行出来的,其中交房租方式是通过类Consumer.java中的splitMonth属性的值控制的。