/**
- java多线程模拟实现12306售票
- 业务描述
- 假设有200张票,用4个线程去订票,不能有两个或者以上的线程订到了
- 同一个票(原因就不说了),当最后一张票卖掉的时候结束,再订就抛
- 异常提示出票卖完了。
- 业务分析,要实现以上功能,
- 1、需要创建一个车票类,初始化票,卖票的接口saleTicket()
- 2、自定义异常的一个类。
- 3、创建卖票线程类,在run方法中卖车票。
- 4、初始化车票的线程,负责初始化车票,也就是初始化Ticket类中的数组。
- 5、创建主方法进行测试。
*/
Test类
package TrainTicket;
public class Test {
public static void main(String[] args) {
// 创建一个初始化线程,若干个买票线程
// 要等初始化线程初始化好了之后,才能买票
// 创建一个Ticket类的对象,分别传给不同的线程
Ticket ticket = new Ticket();
Thread t1 = new InitTicketThread("初始化线程",ticket);
// 等初始化线程初始化好车票之后,才能开始卖票
try {
t1.join(); //t线程优先执行,直到t线程结束。当前线程才可以继续。
} catch (InterruptedException e) {
e.printStackTrace();
}
// 创建四个买票线程,开始卖票
Thread t2 = new SaleTicketThread("窗口1",ticket);
Thread t3 = new SaleTicketThread("窗口2",ticket);
Thread t4 = new SaleTicketThread("窗口3",ticket);
Thread t5 = new SaleTicketThread("窗口4",ticket);
}
}
Ticket类
package TrainTicket;
/**
* java多线程模拟实现12306售票
*
* 业务描述
* 假设有200张票,用4个线程去订票,不能有两个或者以上的线程订到了
* 同一个票(原因就不说了),当最后一张票卖掉的时候结束,再订就抛
* 异常提示出票卖完了。
*
* 业务分析,要实现以上功能,
*
* 1、需要创建一个车票类,初始化票,卖票的接口saleTicket()
*
* 2、自定义异常的一个类。
*
* 3、创建卖票线程类,在run方法中卖车票。
*
* 4、初始化车票的线程,负责初始化车票,也就是初始化Ticket类中的数组。
*
* 5、创建主方法进行测试。
*/
public class Ticket {
//初始化200张票的空间
private String[] tickets = new String[10];
//指向数组的索引(第一张票)
private int index = tickets.length-1;
public Ticket() {
}
// 初始化车票,给数组的元素赋值,考虑是否要同步
public void initTicket(){
for (int i = 0; i <tickets.length; i++) {
tickets[i] = "第"+(i+1)+"号车票";
}
}
// 判断是否有票,有票的情况下再卖票,没有票呢,抛出异常,
// 考虑是否需要同步
public synchronized String saleTicket() throws MyException {
String s = tickets[index];
if (index>=0){
// 故意制造了一个问题,出现多个线程共卖一张车票,必须添加synchronized解决
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tickets[index] = null;
index--;
return s;
}
throw new MyException("已卖完!");
}
}
MyException类
package TrainTicket;
public class MyException extends RuntimeException {
public MyException() {
}
public MyException(String message) {
super(message);
}
}
InitTicketThread类
package TrainTicket;
/**
*初始化车票的线程,负责初始化车票,也就是初始化Ticket类中的数组
* @author mu
*/
public class InitTicketThread extends Thread {
private Ticket ticket;
public InitTicketThread(String name, Ticket ticket) {
super(name);
this.ticket = ticket;
this.start();
}
// 在run方法中初始化车票
@Override
public void run() {
ticket.initTicket();
}
}
SaleTicketThread类
package TrainTicket;
public class SaleTicketThread extends Thread{
private Ticket ticket;
public SaleTicketThread(String name, Ticket ticket) {
super(name);
this.ticket = ticket;
this.start();
}
//run方法中卖车票
@Override
public void run() throws MyException {
for (int i = 0; i <60 ; i++) {
try {
String s = ticket.saleTicket();
System.out.println(this.getName()+"卖票成功————>"+s);
} catch (MyException e) {
System.out.println(this.getName()+"卖票时发生异常!");
e.printStackTrace();
// 如果发生异常,说明没有车票了,就中断循环,不要在卖票了
break;
}
}
}
}