通过多线程的同步于互斥,模拟售票


/**
 * 模拟售票,一个窗口售票,多个买票者购票,票数设为50 主要是利用线程间的同步于互斥
 *
 * 同步:线程2必须在线程1完成后才能进行
 * 互斥:线程2和线程3访问同一变量,一次只能有一个线程访问
 *
 * @author
 *
 */
public class SaleTicket {

 public static void main(String[] args) {
  Ticket t = new Ticket(50);
  setTicket set = new setTicket(t);// 售票线程
  set.start();
  // 买票线程
  for (int i = 1; i <= 52; i++) {
   getTicket get = new getTicket(t, "买票者  " + i + " ");
   get.start();
  }
 }
}
//票对象
class Ticket {
 private int ticketNum;// 票数
 boolean write = false;// 售票与买票间的同步信号量,同一时间只有一张票卖出
 boolean read = true;// 买票者 买票间的信号量,一张票只能卖给一个人

 public Ticket(int ticketNum) {
  this.ticketNum = ticketNum;
 }

 // 取票,票数减一
 public synchronized void getTicket(String name) throws InterruptedException {
  // 售票员正忙,买票者进行等待
  while (!write && read) {
   System.out.println("*****************************" + name
     + " 买票等待。。。");
   this.wait();
  }
  write = false;// 某个买票者要买票,售票员办理即进行等待
  if (ticketNum > 0) {
   read = false;// 让其他买票者等待
   System.out.println("*****************************" + name
     + " 买票成功,号码=" + ticketNum);
   this.subTicketNum();// 销售一张票
   read = true;// 让其他买票者进行买票
   this.notifyAll();
  } else {// 票数为0
   read = false;
   System.out.println("*****************************票已经售完, " + name
     + " 没有买到票");
  }
 }

 // 售票
 public synchronized void sellTicket(String name)
   throws InterruptedException {
  // 只要票数大于0,售票员就一直进行售票
  while (ticketNum > 0) {
   while (write) {
    // 进行售票
    System.out.println(name + " 处理业务,售票等待。。。");
    this.wait();
   }
   if (ticketNum > 0) {
    System.out.println(name + " 开始售票,号码=" + ticketNum);
   }
   write = true;
   this.notifyAll();
  }
  System.out.println(name + " 对不起,售票已经售完!");
 }

 public void subTicketNum() {
  if (this.ticketNum > 0)
   this.ticketNum = this.ticketNum - 1;
 }

 public int getTicketNum() {
  return ticketNum;
 }
}

// 购票者
class getTicket extends Thread {
 Ticket d;// 包含剩余票数
 String name;// 购票者姓名

 public getTicket(Ticket d, String name) {
  this.d = d;
  this.name = name;
 }

 public void run() {
  try {
   d.getTicket(name);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

// 售票员
class setTicket extends Thread {
 Ticket d;

 public setTicket(Ticket d) {
  this.d = d;
 }

 public void run() {
  try {
   d.sellTicket("售票员 1 ");
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值