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