多线程编程之理财

      现实生活中,我们一边工作,一边消费,正常情况下会把多余的钱存起来,比如存到余额宝,还可以多挣点钱,现在就有这个情况:我每月可以发工资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属性的值控制的。

你可能感兴趣的:(java,多线程,生产者,消费者,理财)