Java实验四,星号题最终版(暂定。。。也许还能找到问题)
实验四
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;
}
@Override
public 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();
}
}
else
if(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();
}
}
}
}
else
if(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;
}
@Override
public 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);
}
@Override
public 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);
}
}
}