三个模型类:
帐号类:主要是帐号资金的增加和减少操作,需要sychronized关键字保证线程安全
package thread; /** * create by frank * on 2018/04/20 */ public class Customer{ private int money; public void setMoney(int money) { this.money = money; } public int getMoney() { return money; } public synchronized void add(int money) { this.money += money; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized int out(int money) { int rst = 1; if (this.money >= money){ this.money -= money; }else rst = 2; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } return rst; } }
公司类:公司类功能主要为员工发放工资,调用帐号类的out方法进行工资发放,当帐号内资金少于工资时,公司类进行wait()操作,等到银行类进行资金填充,此期间有以下两个操作
1、释放执行权,其他线程可以进行执行
2、释放对象锁 也就是代码中sychronised() 关键字括号中的customer 对象
package thread; /** * create by frank * on 2018/04/20 */ public class Bank implements Runnable{ private Customer customer; private String name; public Bank(Customer customer){ this.customer = customer; } public String getName() { return name; } @Override public void run() { //对象锁 synchronized (customer){ //获取对象锁和执行权 if(customer.getMoney() < 1000){ customer.add(2000); System.out.println("银行利息到账,余额为:"+customer.getMoney()); //通知Company结束等待 customer.notifyAll(); } } } }
银行类:银行类在公司类资金充裕时不进行帐号资金操作,当公司类进入等待资金填充状态时,银行类进行资金添加,主要调用帐号的add方法进行资金充值,充值完成后进行notifyAll();使得等待资金注入的公司类正常的进行下一步操作。
package thread; /** * create by frank * on 2018/04/20 */ public class Bank implements Runnable{ private Customer customer; private String name; public Bank(Customer customer){ this.customer = customer; } public String getName() { return name; } @Override public void run() { //对象锁 synchronized (customer){ //获取对象锁和执行权 if(customer.getMoney() < 1000){ customer.add(2000); System.out.println("银行利息到账,余额为:"+customer.getMoney()); //通知Company结束等待 customer.notifyAll(); } } } }
测试类:
package thread; /** * create by frank * on 2018/04/20 */ public class Test { public static void main(String[] args) { Customer customer = new Customer(); customer.setMoney(3000); Bank bank = new Bank(customer); Company company = new Company(customer); for (int i = 0; i < 10; i++) { company.run(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } bank.run(); } } }
运行结果:
公司帐号发放工资,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
sleep()、wait()
sleep:释放执行权,但是不是放对象锁
wait:释放执行权和对象锁
notify()、notifyAll();
notify():通知当前等待线程 多线程情况下,可能会因为线程优先级,线程争夺等原因导致结果不同
notifyAll():通知所有等待线程