当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

多线程编程之理财

发表于: 2015-07-16   作者:周凡杨   来源:转载   浏览:
摘要:       现实生活中,我们一边工作,一边消费,正常情况下会把多余的钱存起来,比如存到余额宝,还可以多挣点钱,现在就有这个情况:我每月可以发工资20000万元 (暂定每月的1号),每月消费5000(租房+生活费)元(暂定每月的1号),其中租金是大头占90%,交房租的方式可以选择(一月一交,两月一交、三月一交),理财:1万元存余额宝一天可以赚1元钱,

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

多线程编程之理财

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
在之前的多线程编程的文章中我们讲到了如何使用关键字synchronized加锁来实现同步访问。本文我们继
在之前的多线程编程的文章中我们讲到了如何使用关键字synchronized加锁来实现同步访问。本文我们继
上篇博客我们介绍了一些基本概念,进程、线程、并发。下面我们开始写第一个多线程的程序。 两种方式
Python之多线程编程学习笔记 在一个程序中,这些独立运行的程序片断叫作“线程”(Thread),利用它
function CreateWaitableTimer( lpTimerAttributes: PSecurityAttributes; {安全} bManualReset: BO
之前已经有了两种多线程的同步方法: CriticalSection(临界区) 和 Mutex(互斥), 这两种同步方法差不
据说 Event(事件对象) 是多线程最原始的同步手段, 我觉得它是最灵活的一个. Event 对象(的句柄表)中
原理分析: 互斥对象是系统内核对象, 各线程都可以拥有它, 谁拥有谁就能执行; 执行完毕, 用 ReleaseM
先看一段程序, 代码文件: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Cla
  阅读目录   一:临界区概述   二:临界区操作   三:通过lock关键字设置临界区   四:
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号