多线程同步案例三(家庭消费环境)

============================================

模拟场景:家庭消费多线程

  1. 家庭成员:父亲、母亲、孩子
  2. 家庭有一个公用的金钱账户
  3. 父亲:负责挣钱
  4. 儿子:打游戏
  5. 母亲:购物消费

要求:

  • 不能负债消费!

============================================

一、实体类

Family.java

package net.xiaof.thread2.entity;

/**
 * 家庭实体
 * 
 * @author XIAO
 */
public class Family {

	private Father father; // 父亲
	private Mother mother;// 母亲
	private Child child;// 孩子
	private double accountMoney;// 家庭账户金钱

	public Family() {

	}

	public Father getFather() {
		return father;
	}

	public void setFather(Father father) {
		this.father = father;
	}

	public Mother getMother() {
		return mother;
	}

	public void setMother(Mother mother) {
		this.mother = mother;
	}

	public Child getChild() {
		return child;
	}

	public void setChild(Child child) {
		this.child = child;
	}

	public double getAccountMoney() {
		return accountMoney;
	}

	public void setAccountMoney(double accountMoney) {
		this.accountMoney = accountMoney;
	}

}

Father.java

package net.xiaof.thread2.entity;

/**
 * 父亲实体
 * 
 * @author XIAO
 */
public class Father {

	private String name; // 姓名
	private Family family;// 家庭对象

	public Father() {

	}

	public Father(String name, Family family) {
		super();
		this.name = name;
		this.family = family;
	}

	/**
	 * 赚钱
	 * @param money 金额
	 */
	public void earnMoney(double money) {
		synchronized (this.family) {
			System.out.println(this.name+"充值前,家庭账户金钱:"+this.family.getAccountMoney());
			this.family.setAccountMoney(this.family.getAccountMoney()+money);
			System.out.println(this.name+"充值后,家庭账户金钱:"+this.family.getAccountMoney());
		}
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Family getFamily() {
		return family;
	}

	public void setFamily(Family family) {
		this.family = family;
	}

}

Mother.java

package net.xiaof.thread2.entity;

/**
 * 母亲实体
 * 
 * @author XIAO
 */
public class Mother {

	private String name; // 姓名
	private Family family;// 家庭对象

	public Mother() {

	}

	public Mother(String name, Family family) {
		super();
		this.name = name;
		this.family = family;
	}

	/**
	 * 购物
	 * 
	 * @param money
	 *            消费金额
	 */
	public void shopping(double money) {
		synchronized (this.family) {
			System.out.println(this.name + "购物前,家庭账户金钱:" + this.family.getAccountMoney());
			if (this.family.getAccountMoney() >= money) {
				this.family.setAccountMoney(this.family.getAccountMoney() - money);
				System.out.println("        " + this.name + "消费金钱:" + money);
			} else {
				System.out.println("☹  !账户金额不足,请【" + this.name + "】暂停消费");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Family getFamily() {
		return family;
	}

	public void setFamily(Family family) {
		this.family = family;
	}

}

Child.java

package net.xiaof.thread2.entity;

/**
 * 孩子实体
 * 
 * @author XIAO
 */
public class Child {

	private String name; // 姓名
	private Family family;// 家庭对象

	public Child() {

	}

	public Child(String name, Family family) {
		super();
		this.name = name;
		this.family = family;
	}

	/**
	 * 玩游戏
	 * 
	 * @param money
	 *            消费金额
	 */
	public void playGames(double money) {
		synchronized (this.family) {
			System.out.println(this.name + "打游戏前,家庭账户金钱:" + this.family.getAccountMoney());
			if (this.family.getAccountMoney() >= money) {
				this.family.setAccountMoney(this.family.getAccountMoney() - money);
				System.out.println("        " + this.name + "消费金钱:" + money);
			} else {
				System.out.println("☹  !账户金额不足,请【" + this.name + "】暂停消费");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Family getFamily() {
		return family;
	}

	public void setFamily(Family family) {
		this.family = family;
	}

}


二、线程任务类

【注】:此处测试,由于while循环没有结束条件(或结束标志),所以在添加同步(synchronized)时,应添加在while(true){ }内部中,否则 模拟时,只要有一个线程进行家庭消费(减金额),其他消费线程则不能进入。

FatherTask.java

package net.xiaof.thread2.task;

import net.xiaof.thread2.entity.Father;

/**
 * 父亲线程任务类:父亲赚钱
 * 
 * @author XIAO
 *
 */
public class FatherTask implements Runnable {

	private Father father;

	public FatherTask(Father father) {
		this.father = father;
	}

	@Override
	public void run() {
		while (true) {
			this.father.earnMoney(30); // 消费30
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

MotherTask.java

package net.xiaof.thread2.task;

import net.xiaof.thread2.entity.Mother;

/**
 * 母亲线程任务类:母亲购物花钱
 * 
 * @author XIAO
 *
 */
public class MotherTask implements Runnable {

	private Mother mother;

	public MotherTask(Mother mother) {
		this.mother = mother;
	}

	@Override
	public void run() {
		while (true) {
			this.mother.shopping(10); // 消费10
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

ChildTask.java

package net.xiaof.thread2.task;

import net.xiaof.thread2.entity.Child;

/**
 * 孩子线程任务类:孩子玩游戏花钱
 * 
 * @author XIAO
 *
 */
public class ChildTask implements Runnable {

	private Child child;

	public ChildTask(Child child) {
		this.child = child;
	}

	@Override
	public void run() {
		while (true) {
			this.child.playGames(10); // 消费10
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}


三、测试类

package net.xiaof.thread2.test;

import net.xiaof.thread2.entity.Child;
import net.xiaof.thread2.entity.Family;
import net.xiaof.thread2.entity.Father;
import net.xiaof.thread2.entity.Mother;
import net.xiaof.thread2.task.ChildTask;
import net.xiaof.thread2.task.FatherTask;
import net.xiaof.thread2.task.MotherTask;

/**
 * 测试类
 * @author XIAO
 */
public class TestDemo {
	
	public static void main(String[] args) {
		//实例化一个家庭
		Family family = new Family();
		Father father = new Father("父亲", family);
		Mother mother = new Mother("母亲", family);
		Child child = new Child("孩子", family);
		
		//开启多线程
		FatherTask fatherTask = new FatherTask(father);
		Thread t1 = new Thread(fatherTask);
		t1.start();
		
		MotherTask motherTask = new MotherTask(mother);
		Thread t2 = new Thread(motherTask);
		t2.start();
		
		ChildTask childTask = new ChildTask(child);
		Thread t3 = new Thread(childTask);
		t3.start();
	}
	
}


三、控制台输出

父亲充值前,家庭账户金钱:0.0
父亲充值后,家庭账户金钱:30.0
孩子打游戏前,家庭账户金钱:30.0
        孩子消费金钱:10.0
母亲购物前,家庭账户金钱:20.0
        母亲消费金钱:10.0
孩子打游戏前,家庭账户金钱:10.0
        孩子消费金钱:10.0
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
父亲充值前,家庭账户金钱:0.0
父亲充值后,家庭账户金钱:30.0
母亲购物前,家庭账户金钱:30.0
        母亲消费金钱:10.0
孩子打游戏前,家庭账户金钱:20.0
        孩子消费金钱:10.0
母亲购物前,家庭账户金钱:10.0
        母亲消费金钱:10.0
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
父亲充值前,家庭账户金钱:0.0
父亲充值后,家庭账户金钱:30.0
孩子打游戏前,家庭账户金钱:30.0
        孩子消费金钱:10.0
母亲购物前,家庭账户金钱:20.0
        母亲消费金钱:10.0
孩子打游戏前,家庭账户金钱:10.0
        孩子消费金钱:10.0
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
☹  !账户金额不足,请【孩子】暂停消费
母亲购物前,家庭账户金钱:0.0
☹  !账户金额不足,请【母亲】暂停消费
孩子打游戏前,家庭账户金钱:0.0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值