题意 :
电影院卖票 : 售票员初始时有3张5元的票 。每张票5元。
三个人来买票 。一个人手里有5元,一个人手里有10元。一个人手里有20元。如果有零钱则购票成功,否则进行排队
思路:把售票员的票单独定义一个类 ,用于存放初始的票数 。
实现3个Runnable 类使用售票员类作为成员变量。三个类作为三位手持不同面额来进行购票的顾客。
ticket类
package com.SellTicket;
public class Ticket {
public int a5 = 3;
public int a10 = 0;
public int a20 = 0;
public Ticket() {
}
public void SetTicket(int t1,int t2,int t3) {
this.a5 += t1;
this.a10 += t2;
this.a20 += t3;
}
public void getTicket() {
System.out.println("五元:" + a5+" 十元:"+a10+" 二十元:"+a20 +"总额为"+(a5*5+a10*10+a20*20));
}
}
三位顾客
package com.SellTicket;
public class C1 implements Runnable{
public Ticket ticket;
public C1(Ticket tickets) {
this.ticket = tickets;
}
@Override
public void run() {
synchronized(ticket) {//定义我是拿5元来买票的
System.out.println(Thread.currentThread().getName() + "购票成功");
ticket.SetTicket(1, 0, 0);
ticket.getTicket();//打印当前零钱信息
ticket.notifyAll();//唤醒其他全部等待的线程
}
}
}
package com.SellTicket;
public class C2 implements Runnable{
public Ticket ticket;
public C2(Ticket ticket1) {
this.ticket = ticket1;
}
@Override
public void run() {//定义我是拿10元买票的
synchronized(ticket) {
if(ticket.a5 <=0) {//我要进入等待状态
System.out.println(Thread.currentThread().getName()+"现在没有零钱,我要进入等待状态");
try {
ticket.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//到了这里说明ticket.a5 > 0了 我拿10元钱也能买票了
System.out.println(Thread.currentThread().getName()+"购票成功");
ticket.SetTicket(-1, 1, 0);//5元少一张 ,10元多一张
ticket.getTicket();//打印当前零钱信息
ticket.notifyAll();//唤醒全部等待线程
}
}
}
package com.SellTicket;
public class C3 implements Runnable{
public Ticket ticket;
public C3(Ticket tickets) {
this.ticket = tickets;
}
@Override
public void run() {
// 我就是拿20元钱来买票的人
synchronized(ticket) {
if(ticket.a5 < 3 && (ticket.a5 < 1 && ticket.a10 < 1)){
System.out.println(Thread.currentThread().getName() +"现在没有零钱,我需要等待");
try {
ticket.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "购票成功");
if(ticket.a5 >= 3) {//我用3张5元钱进行找零
ticket.SetTicket(-3, 0, 1);//5元少3张 ,20元多一张
}else {
ticket.SetTicket(-1, -1, 1);//5元少一张,10元少一张,20元多一张
}
ticket.getTicket();//获取当前票数信息
ticket.notifyAll();
}
}
}
实现类:
package com.SellTicket;
public class Demo {
public static void main(String[] args) {
Ticket ticket =new Ticket();
C1 c1 = new C1(ticket);
C2 c2 = new C2(ticket);
C3 c3 = new C3(ticket);
Thread t1 = new Thread(c1,"5元来买票");
Thread t2 = new Thread(c2,"10元来买票");
Thread t3 = new Thread(c3,"20元来买票");
t1.start();
t2.start();
t3.start();
}
}
运行结果:


本文介绍了一个基于Java的电影票售卖系统案例,通过线程同步机制处理不同金额购票情况,确保售票过程中的零钱找补正确无误。文章详细展示了如何使用synchronized关键字和wait/notifyAll方法实现多线程间的同步与等待,解决因零钱不足导致的购票延迟问题。
288

被折叠的 条评论
为什么被折叠?



