实验四

  • 1、 第一版使用wait、notifyAll、synchronized ,可以买到票但是排序不行
  • 2、 第二版 第一次使用公平锁、ReentrantLock、Condition,感觉还是没解决排序问题
  • 3、最终版(暂定为最终版)解决了排序问题。。。。仅仅只是在公平锁的前提下,加入sleep,start一个sleep一会儿,貌似解决了排序问题

1、 第一版使用wait、notifyAll、synchronized ,可以买到票但是排序不行

只能支持输入仅有n张五元钱其余为0张
或者仅有n张10元钱,其余为0张
或者仅有n张20元钱,其余为0张

主要执行函数:
giveChange():
用 sychronized 关键字加对象锁,无法找零或者钱不够买票的时候,线程wait
否则进行找零或者直接出票,然后执行 notifyALL方法,尝试唤醒所有线程,当被wait的线程发现资源已经满足,可以找零的时候,开始再次加入自由抢占的线程大军
实现的功能:大概率确保能买票
还没实现的功能:按顺序排队买票的顺序

package Ex4.Thirdquestion;/*** @author 15328* *3、编写Java应用程序模拟5个人排队买票。* 售票员只有1张五元的钱,电影票五元钱一张。* 假设5个人的名字及排队顺序是:赵、钱、孙、李、周。* “赵”拿1张二十元的人民币买2张票,* “钱”拿1张二十元的人民币买1张票,* “孙”1张十元的人民币买1张票,* “李”拿1张十元的人民币买2张票,* “周”拿1张五元的人民币买1张票。* 要求售票员按如下规则找赎:* (1)二十元买1张票,找零:1张十元;不许找零2张五元。* (2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。* (3)十元买一张票,找零1张五元。*/
public class Buy extends Thread {Money money;private  int fiveOfNumber;private  int tenOfNumber;private  int twentyOfNumber;private int ticketOfNum;private String name;public Buy(Money money,int fiveOfNumber, int tenOfNumber, int twentyOfNumber,int ticketOfNum,String name) {this.fiveOfNumber = fiveOfNumber;this.tenOfNumber = tenOfNumber;this.twentyOfNumber = twentyOfNumber;this.ticketOfNum = ticketOfNum;this.money = money;this.name = name;}@Overridepublic void run() {try {Thread.currentThread().setName(this.name);money.givechange(fiveOfNumber,tenOfNumber,twentyOfNumber,ticketOfNum,Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}}
}class Money{private  static int fiveOfNum = 1;private  static int tenOfNum = 0;private  static int twentyOfNum = 0;public  synchronized void givechange(int fiveOfNumber,int tenOfNumber,int twentyOfNumber,int ticketOfNumber,String name) throws InterruptedException {System.out.print(name+ " ");if(fiveOfNumber !=0 && tenOfNumber==0 && twentyOfNumber==0) {if(ticketOfNumber > fiveOfNumber) {System.out.println("钱不够买票");return;}else {System.out.print("客户原有" + fiveOfNumber + "张5元," + ",买票总钱数是:" + (ticketOfNumber * 5));fiveOfNumber -= ticketOfNumber;fiveOfNum += ticketOfNumber;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}}elseif(fiveOfNumber==0 && tenOfNumber!=0 && twentyOfNumber==0) {if(ticketOfNumber*5 > tenOfNumber*10){System.out.println("钱不够买票");return;}else{if(ticketOfNumber % 2 == 0) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是:" + (ticketOfNumber * 5));tenOfNumber -= ticketOfNumber / 2;tenOfNum += ticketOfNumber / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}else{//买奇数张票,有一张需要找零if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");Thread.currentThread().setPriority(Thread.MAX_PRIORITY);this.wait();//Thread.sleep(5);System.out.print(name+ " ");}if(!(fiveOfNum <= 0)) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum += (ticketOfNumber + 1) / 2;tenOfNumber -= (ticketOfNumber + 1) / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 找零5元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}}}}elseif(fiveOfNumber==0 && tenOfNumber==0 && twentyOfNumber!=0){if(ticketOfNumber * 5 > twentyOfNumber * 20) {System.out.println("钱不够买票");return;}else{if(ticketOfNumber % 2 == 0) {if(ticketOfNumber >= 4 && ticketOfNumber%4 == 0) {//4的倍数System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));twentyOfNumber -= ticketOfNumber / 4;twentyOfNum += ticketOfNumber / 4;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}else{//只是2的倍数,不是4的倍数,找一张10元零钱//2、6、10、14、System.out.print("客户原有" + twentyOfNumber + "张20元,"+",买票总钱数是: " + (ticketOfNumber * 5)  );if(tenOfNum <= 0) {System.out.println("要找零一张十元钱,但是没有,线程睡眠");Thread.currentThread().setPriority(Thread.MAX_PRIORITY);this.wait();//Thread.sleep(5);System.out.print(name+ " ");}if(!(tenOfNum <= 0)) {tenOfNum--;tenOfNumber++;twentyOfNum += (ticketOfNumber + 2) / 4;twentyOfNumber -= (ticketOfNumber + 2) / 4;System.out.print("客户原有" + twentyOfNumber + "张20元,"+",买票总钱数是: " + (ticketOfNumber * 5)  );System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零10元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}}}else {//不是2的倍数的时候if((ticketOfNumber - 1) % 4 == 0) {//1、5、9、、、、、if(tenOfNum <= 0 || fiveOfNum <= 0) {System.out.println("要找零一张五元钱和一张十元钱,但是没有,线程睡眠");Thread.currentThread().setPriority(Thread.MAX_PRIORITY);this.wait();//Thread.sleep(5);System.out.print(name+ " ");}if(!(tenOfNum <= 0 || fiveOfNum <= 0)){System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum--;tenOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张10元和一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}} else if((ticketOfNumber + 1) % 4 == 0) {//3、7、11、、、、、if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");Thread.currentThread().setPriority(Thread.MAX_PRIORITY);this.wait();//Thread.sleep(5);System.out.print(name+ " ");}if(!(fiveOfNum <= 0)){System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");this.notifyAll();}}}}}}}class TicketSeller{public static void main(String[] args) {Money money = new Money();/*new Buy(money, 0, 4, 0,3,"1号").start();new Buy(money, 0, 0, 1,3,"2号").start();new Buy(money, 0, 0, 1,1,"3号").start();new Buy(money, 0, 1, 0,2,"4号").start();new Buy(money, 0, 3, 0,4,"5号").start();new Buy(money, 3, 0, 0,3,"6号").start();new Buy(money, 3, 0, 0,4,"7号").start();new Buy(money, 0, 0, 2,4,"8号").start();new Buy(money, 0, 0, 2,8,"9号").start();new Buy(money, 0, 0, 2,7,"10号").start();*/new Buy(money, 0, 0, 1,2,"赵").start();new Buy(money, 0, 0, 1,1,"钱").start();new Buy(money, 0, 1, 0,1,"孙").start();new Buy(money, 0, 1, 0,2,"李").start();new Buy(money, 1, 0, 0,1,"周").start();}
}

2、 第二版 第一次使用公平锁、ReentrantLock、Condition,感觉还是没解决排序问题

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @author 15328* *3、编写Java应用程序模拟5个人排队买票。* 售票员只有1张五元的钱,电影票五元钱一张。* 假设5个人的名字及排队顺序是:赵、钱、孙、李、周。* “赵”拿1张二十元的人民币买2张票,* “钱”拿1张二十元的人民币买1张票,* “孙”1张十元的人民币买1张票,* “李”拿1张十元的人民币买2张票,* “周”拿1张五元的人民币买1张票。* 要求售票员按如下规则找赎:* (1)二十元买1张票,找零:1张十元;不许找零2张五元。* (2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。* (3)十元买一张票,找零1张五元。*/
public class Buy extends Thread {Money money;private  int fiveOfNumber;private  int tenOfNumber;private  int twentyOfNumber;private int ticketOfNum;private String name;public Buy(Money money,int fiveOfNumber, int tenOfNumber, int twentyOfNumber,int ticketOfNum,String name) {this.fiveOfNumber = fiveOfNumber;this.tenOfNumber = tenOfNumber;this.twentyOfNumber = twentyOfNumber;this.ticketOfNum = ticketOfNum;this.money = money;this.name = name;}@Overridepublic void run() {Thread.currentThread().setName(this.name);money.givechange(fiveOfNumber,tenOfNumber,twentyOfNumber,ticketOfNum,Thread.currentThread().getName());}
}class Money{private  static int fiveOfNum = 1;private  static int tenOfNum = 0;private  static int twentyOfNum = 0;public Lock lock;public Condition condition;public Money(boolean fair){lock = new ReentrantLock(fair);condition = lock.newCondition();}public  void givechange(int fiveOfNumber,int tenOfNumber,int twentyOfNumber,int ticketOfNumber,String name) {try {lock.lock();System.out.print(name + " ");if(fiveOfNumber != 0 && tenOfNumber == 0 && twentyOfNumber == 0) {if(ticketOfNumber > fiveOfNumber) {System.out.println("钱不够买票");lock.unlock();return;} else {System.out.print("客户原有" + fiveOfNumber + "张5元," + ",买票总钱数是:" + (ticketOfNumber * 5));fiveOfNumber -= ticketOfNumber;fiveOfNum += ticketOfNumber;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}} else if(fiveOfNumber == 0 && tenOfNumber != 0 && twentyOfNumber == 0) {if(ticketOfNumber * 5 > tenOfNumber * 10) {System.out.println("钱不够买票");lock.unlock();return;} else {if(ticketOfNumber % 2 == 0) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是:" + (ticketOfNumber * 5));tenOfNumber -= ticketOfNumber / 2;tenOfNum += ticketOfNumber / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();} else {//买奇数张票,有一张需要找零if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);condition.await();//Thread.sleep(5);System.out.print(name + " ");}if(!(fiveOfNum <= 0)) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum += (ticketOfNumber + 1) / 2;tenOfNumber -= (ticketOfNumber + 1) / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 找零5元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}}}} else if(fiveOfNumber == 0 && tenOfNumber == 0 && twentyOfNumber != 0) {if(ticketOfNumber * 5 > twentyOfNumber * 20) {System.out.println("钱不够买票");lock.unlock();return;} else {if(ticketOfNumber % 2 == 0) {if(ticketOfNumber >= 4 && ticketOfNumber % 4 == 0) {//4的倍数System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));twentyOfNumber -= ticketOfNumber / 4;twentyOfNum += ticketOfNumber / 4;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();} else {//只是2的倍数,不是4的倍数,找一张10元零钱//2、6、10、14、System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));if(tenOfNum <= 0) {System.out.println("要找零一张十元钱,但是没有,线程睡眠");//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);condition.await();//Thread.sleep(5);System.out.print(name + " ");}if(!(tenOfNum <= 0)) {tenOfNum--;tenOfNumber++;twentyOfNum += (ticketOfNumber + 2) / 4;twentyOfNumber -= (ticketOfNumber + 2) / 4;System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零10元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}}} else {//不是2的倍数的时候if((ticketOfNumber - 1) % 4 == 0) {//1、5、9、、、、、if(tenOfNum <= 0 || fiveOfNum <= 0) {System.out.println("要找零一张五元钱和一张十元钱,但是没有,线程睡眠");//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);condition.await();//Thread.sleep(5);System.out.print(name + " ");}if(!(tenOfNum <= 0 || fiveOfNum <= 0)) {System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum--;tenOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张10元和一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}} else if((ticketOfNumber + 1) % 4 == 0) {//3、7、11、、、、、if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);condition.await();//Thread.sleep(5);System.out.print(name + " ");}if(!(fiveOfNum <= 0)) {System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}}}}}lock.unlock();} catch (InterruptedException e) {e.printStackTrace();}}}class TicketSeller{public static void main(String[] args) {Money money = new Money(true);/*new Buy(money, 0, 4, 0,3,"1号").start();new Buy(money, 0, 0, 1,3,"2号").start();new Buy(money, 0, 0, 1,1,"3号").start();new Buy(money, 0, 1, 0,2,"4号").start();new Buy(money, 0, 3, 0,4,"5号").start();new Buy(money, 3, 0, 0,3,"6号").start();new Buy(money, 3, 0, 0,4,"7号").start();new Buy(money, 0, 0, 2,4,"8号").start();new Buy(money, 0, 0, 2,8,"9号").start();new Buy(money, 0, 0, 2,7,"10号").start();*/new Buy(money, 0, 0, 1,2,"赵").start();new Buy(money, 0, 0, 1,1,"钱").start();new Buy(money, 0, 1, 0,1,"孙").start();new Buy(money, 0, 1, 0,2,"李").start();new Buy(money, 1, 0, 0,1,"周").start();}}

3、最终版(暂定为最终版)解决了排序问题。。。。仅仅只是在公平锁的前提下,加入sleep,start一个sleep一会儿,貌似解决了排序问题

感觉是赵钱都被阻塞,阻塞队列里赵在前,所以当一旦满足条件,赵先“解封”,而即使之前已经满足“解封”钱的条件,也要先等赵,参考下面的23号也是这样

package Ex4.Thirdquestion;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** @author 15328* *3、编写Java应用程序模拟5个人排队买票。* 售票员只有1张五元的钱,电影票五元钱一张。* 假设5个人的名字及排队顺序是:赵、钱、孙、李、周。* “赵”拿1张二十元的人民币买2张票,* “钱”拿1张二十元的人民币买1张票,* “孙”1张十元的人民币买1张票,* “李”拿1张十元的人民币买2张票,* “周”拿1张五元的人民币买1张票。* 要求售票员按如下规则找赎:* (1)二十元买1张票,找零:1张十元;不许找零2张五元。* (2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。* (3)十元买一张票,找零1张五元。*/
public class Buy extends Thread {Money money;private  int fiveOfNumber;private  int tenOfNumber;private  int twentyOfNumber;private int ticketOfNum;private String name;public Buy(Money money,int fiveOfNumber, int tenOfNumber, int twentyOfNumber,int ticketOfNum,String name) {this.fiveOfNumber = fiveOfNumber;this.tenOfNumber = tenOfNumber;this.twentyOfNumber = twentyOfNumber;this.ticketOfNum = ticketOfNum;this.money = money;this.name = name;Thread.currentThread().setName(this.name);}@Overridepublic void run() {Thread.currentThread().setName(this.name);money.givechange(fiveOfNumber,tenOfNumber,twentyOfNumber,ticketOfNum,Thread.currentThread().getName());}
}class Money {private static int fiveOfNum = 1;private static int tenOfNum = 0;private static int twentyOfNum = 0;public Lock lock;public Condition condition;public Money(boolean fair){lock = new ReentrantLock(fair);condition = lock.newCondition();}public void givechange1(int fiveOfNumber, int tenOfNumber, int twentyOfNumber, int ticketOfNumber, String name) {System.out.print("客户原有" + fiveOfNumber + "张5元," + ",买票总钱数是:" + (ticketOfNumber * 5));fiveOfNumber -= ticketOfNumber;fiveOfNum += ticketOfNumber;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();
}public void givechange2(int fiveOfNumber, int tenOfNumber, int twentyOfNumber, int ticketOfNumber, String name) throws InterruptedException {if(ticketOfNumber % 2 == 0) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是:" + (ticketOfNumber * 5));tenOfNumber -= ticketOfNumber / 2;tenOfNum += ticketOfNumber / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");} else {//买奇数张票,有一张需要找零if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");condition.await();System.out.print(name + " ");}if(!(fiveOfNum <= 0)) {System.out.print("客户原有" + tenOfNumber + "张10元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum += (ticketOfNumber + 1) / 2;tenOfNumber -= (ticketOfNumber + 1) / 2;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 找零5元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");}}}public void givechange3(int fiveOfNumber, int tenOfNumber, int twentyOfNumber, int ticketOfNumber, String name) throws InterruptedException {if(ticketOfNumber % 2 == 0) {if(ticketOfNumber >= 4 && ticketOfNumber % 4 == 0) {//4的倍数System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));twentyOfNumber -= ticketOfNumber / 4;twentyOfNum += ticketOfNumber / 4;System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " 不用找零,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();} else {//只是2的倍数,不是4的倍数,找一张10元零钱//2、6、10、14、System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));if(tenOfNum <= 0) {System.out.println("要找零一张十元钱,但是没有,线程睡眠");condition.await();System.out.print(name + " ");}if(!(tenOfNum <= 0)) {tenOfNum--;tenOfNumber++;twentyOfNum += (ticketOfNumber + 2) / 4;twentyOfNumber -= (ticketOfNumber + 2) / 4;System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元" + ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零10元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}}} else {//不是2的倍数的时候if((ticketOfNumber - 1) % 4 == 0) {//1、5、9、、、、、if(tenOfNum <= 0 || fiveOfNum <= 0) {System.out.println("要找零一张五元钱和一张十元钱,但是没有,线程睡眠");condition.await();System.out.print(name + " ");}if(!(tenOfNum <= 0 || fiveOfNum <= 0)) {System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;tenOfNum--;tenOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张10元和一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}} else if((ticketOfNumber + 1) % 4 == 0) {//3、7、11、、、、、if(fiveOfNum <= 0) {System.out.println("要找零一张五元钱,但是没有,线程睡眠");condition.await();System.out.print(name + " ");}if(!(fiveOfNum <= 0)) {System.out.print("客户原有" + twentyOfNumber + "张20元," + ",买票总钱数是: " + (ticketOfNumber * 5));fiveOfNum--;fiveOfNumber++;twentyOfNumber -= (ticketOfNumber / 4 + 1);twentyOfNum += (ticketOfNumber / 4 + 1);System.out.println(", 客户现有" + fiveOfNumber + "张5元" + ", 客户现有" + tenOfNumber + "张10元"+ ", 客户现有" + twentyOfNumber + "张20元" + " ,要找零一张五元,现在售货员剩余五元:" + fiveOfNum + "张"+ " 、十元: " + tenOfNum + "张" + " 、 二十元: " + twentyOfNum + "张");condition.signalAll();}}}}public void givechange(int fiveOfNumber,int tenOfNumber,int twentyOfNumber,int ticketOfNumber,String name)  {try {lock.lock();System.out.print(name + " ");if(fiveOfNumber != 0 && tenOfNumber == 0 && twentyOfNumber == 0) {if(ticketOfNumber > fiveOfNumber) {System.out.println("钱不够买票");return;} else {givechange1(fiveOfNumber, tenOfNumber, twentyOfNumber, ticketOfNumber, name);}} else if(fiveOfNumber == 0 && tenOfNumber != 0 && twentyOfNumber == 0) {if(ticketOfNumber * 5 > tenOfNumber * 10) {System.out.println("钱不够买票");return;} else {givechange2(fiveOfNumber, tenOfNumber, twentyOfNumber, ticketOfNumber, name);}} else if(fiveOfNumber == 0 && tenOfNumber == 0 && twentyOfNumber != 0) {if(ticketOfNumber * 5 > twentyOfNumber * 20) {System.out.println("钱不够买票");return;} else {givechange3(fiveOfNumber, tenOfNumber, twentyOfNumber, ticketOfNumber, name);}} else {System.out.println("非法输入");}} catch (InterruptedException interruptedException) {interruptedException.printStackTrace();} finally {lock.unlock();}}
}class TicketSeller{public static void main(String[] args) throws InterruptedException {Money money = new Money(true);/*new Buy(money, 0, 4, 0,3,"1号").start();Thread.sleep(100);new Buy(money, 0, 0, 1,3,"2号").start();Thread.sleep(100);new Buy(money, 0, 0, 1,1,"3号").start();Thread.sleep(100);new Buy(money, 0, 1, 0,2,"4号").start();Thread.sleep(100);new Buy(money, 0, 3, 0,4,"5号").start();Thread.sleep(100);new Buy(money, 3, 0, 0,3,"6号").start();Thread.sleep(100);new Buy(money, 3, 0, 0,4,"7号").start();Thread.sleep(100);new Buy(money, 0, 0, 2,4,"8号").start();Thread.sleep(100);new Buy(money, 0, 0, 2,8,"9号").start();Thread.sleep(100);new Buy(money, 0, 0, 2,7,"10号").start();Thread.sleep(100);*/Buy [] buys = new Buy[5];buys [0] = new Buy(money, 0, 0, 1,2,"赵");buys[0].setName("赵");buys [1] = new Buy(money, 0, 0, 1,1,"钱");buys[1].setName("钱");buys [2] = new Buy(money, 0, 1, 0,1,"孙");buys[2].setName("孙");buys [3] = new Buy(money, 0, 1, 0,2,"李");buys[3].setName("李");buys [4] = new Buy(money, 1, 0, 0,1,"周");buys[4].setName("周");for(int i = 0; i < 5; i++) {buys[i].start();Thread.sleep(100);}}
}

Java实验四,星号题最终版(暂定。。。也许还能找到问题)相关推荐

  1. 西农大 Java 实验四 第一题

    任务一:界面设计 请设计一个界面,包括:菜单,文本框,按钮,标签,文本区,选择框,单选按钮和下拉列表. package first;import java.awt.BorderLayout; impo ...

  2. 面试题:460道Java后端面试高频题答案版「模块九:Spring」

    Spring 写在前面 相信对于 Spring 这个模块,只要是做过 Java 开发的同学都是不陌生的,或多或少都使用过 Spring 体系的框架.对于平时自己做点小项目会写配置文件可能就行了,但是对 ...

  3. java实验四云南大学_云南大学软件学院Java实验四

    云南大学软件学院Java实验四 云南大学软件学院 实 验 报 告 姓名: 王定欢 学号: 班级: 日期: 2016.10.13 成绩: JAVA实验四 一. 实验目的: Fundamental Pro ...

  4. java实验四结果,java实验四异常处理.doc

    java实验四异常处理.doc 实验四异常处理一.实验目的1.掌握异常的概念和Java异常处理机制.2.掌握异常的定义.抛出和捕捉处理.二.实验内容与要求1.仔细读下面的JAVA语言源程序,自己给出程 ...

  5. 阿里巴巴Java开发手册一周年最终版

    阿里巴巴Java开发手册一周年最终版 摘要:阿里巴巴集团推出的<阿里巴巴Java开发手册>是阿里巴巴近万名开发同学集体智慧的结晶,以开发视角为中心,详细列举如何开发更加高效.更加容错.更加 ...

  6. #20165323 Java实验四 Android程序设计

    一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:杨金川 学号:20165323 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 15:25 实验序号:实验 ...

  7. java实验四用户程序设计_20145329《Java程序设计》实验四总结

    实验四 Android环境搭建 实验内容 1.搭建Android环境 2.运行Android 3.修改代码,能输出学号 实验步骤 1.搭建Android环境 2.安装Android,核心是配置JDK. ...

  8. java实验四——找鞍点

    package hello;public class 实验四 {public static void main(String[] args) {// TODO Auto-generated metho ...

  9. java实验四云南大学_云南大学软件学院JAVA实验八

    云南大学软件学院 实验报告 姓名:王增伟学号:20111120083 班级:软件工程日期:2014.11.11成绩: JAVA实验八 一.实验目的: 熟悉图形化界面编程,学会用程序画简单的图形.书写文 ...

最新文章

  1. 【转发】什么时候该用委托,为什么要用委托,委托有什么好处
  2. 科研经验3:公众号建立实验室共享知识体系和宣传窗口
  3. 《交互式程序设计 第2版》一2.7 作用域
  4. kafka在zk中的目录
  5. 请先设置tkk_搅拌站水泥罐仓顶除尘器设置及调整
  6. MediaPlayer 播放视频的方法
  7. linux 自定义vi dd,Vim常用命令及配置方案
  8. idea git将多余的代码提交到本地,如何退回。
  9. iNFTnews | 周杰伦18年前未发布的作品Demo,藏在了区块链技术里
  10. 在我的ibmR40上装osx86
  11. 密码编码学与网络安全-------原理与实践(第七版)
  12. 湖南师范大学学科综合评价计算机,师范类高校自主招生/综合评价相关问答,2020届参考...
  13. Nacos源码系列之服务发现(二)
  14. 软件测试面试过程中的一些回答思路及技巧,学会了稳过
  15. 阈的粤语发音_粤语发音规则完整版
  16. CUDA C程序没报错 结果不对 找不到问题 的一种可能的问题hhhh....
  17. iOS冰与火之歌番外篇 - 在非越狱手机上进行App Hook(转载)
  18. linux setfont设置大小,setfont命令
  19. 没有最好只有更好,本届云栖大会的无线网络如何创造奇迹?
  20. 谷歌的ie9.js ie8.js ie7.js 解决IE5、IE6、IE7、IE8与W3C标准的冲突

热门文章

  1. 【JavaSE】生成1-10随机数
  2. android开发文本字体包,AndroidStudio 实现加载字体资源的方法
  3. Flink 数据湖 助力美团数仓增量生产
  4. CentOS 配置 yum 源
  5. iphone内存管理
  6. 手机怎么投屏到电视?苹果手机投屏的三种方法
  7. 使用OneNote UWP编辑公式
  8. 《代码大全2》第14章 组织直线型代码
  9. mysql新增字段顺序_mysql 添加字段、删除字段、调整字段顺序 转
  10. 20 个超酷的 HTML5/CSS3 应用及源码