用synchronized、notify、wait实现一个火车票卖票程序

本文介绍了如何使用Java中的synchronized、notify和wait关键字实现一个火车票卖票程序,通过创建Ticket类来模拟售票和取票的过程,并通过PutTicketThread和SellTicketThread线程类来实现生产者和消费者的功能。为了确保线程间的正确同步,当票售罄时会使用wait方法挂起线程,直到有新票可用时通过notify或notifyAll方法唤醒等待的线程。

昨天面试一公司,应面试官要求,用synchronized、notify、wait实现一个火车票卖票程序,要求生成者不断的往队列中插入唯一的票通知消费者取票,消费者取走这唯一的票再通知生产者放票,如此循环。

参照疯狂Java讲义中存钱的例子实现,代码如下:
Ticket.java

import java.util.ArrayDeque;


public class Ticket {
	ArrayDeque ticket = new ArrayDeque();
	long ticketNum = 1;
	public synchronized void sell()//售票函数
	{
		try 
		{
			System.out.println("当前票数量:" + ticket.size());
			if(ticket.size() > 0) //取票
			{
				System.out.println(Thread.currentThread().getName() +  
						" 取走第:" +  ticket.pop() + "张票.");
				notify();
			}
			else
			{	
				System.out.println(Thread.currentThread().getName() +  
						"等待售票员放票.");
			//	Thread.sleep(1000);
				wait();//等待放票				
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public synchronized void put()
	{
		try 
		{
			System.out.println("当前票数量:" + ticket.size());
			if(ticket.size() > 0)
			{
				System.out.println(Thread.currentThread().getName() +  
						"等待乘客取票.");
				//Thread.sleep(1000);
				wait();//等待取票	
			}
			else//放票
			{	
				ticket.push(ticketNum);	
				System.out.println(Thread.currentThread().getName() +  
						"放入第:" +  ticketNum + "张票.");
				ticketNum ++;
				notify();
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

PutTicketThread.java

public class PutTicketThread extends Thread{
	private Ticket ticket;
	
	public PutTicketThread(String name, Ticket ticket)
	{
		super(name);
		this.ticket = ticket;
	}
	
	public void run(){
		while(true)//循环放票
		{
			ticket.put();
		}
	}

}

SellTicketThread.java

public class SellTicketThread extends Thread {
	private Ticket ticket;

	public SellTicketThread(String name, Ticket ticket) {
		super(name);
		this.ticket = ticket;
	}

	public void run() {
		while (true) {//循环取票
			ticket.sell();
		}
	}
}

TestMain.java

public class TestMain {
	public static void main(String[] args) throws InterruptedException 
	{
		Ticket ticket = new Ticket();
		new PutTicketThread("售票员 1", ticket).start();
		//new PutTicketThread("售票员 2", ticket).start();
		new SellTicketThread("张三", ticket).start();
		//new SellTicketThread("李四", ticket).start();
		//new SellTicketThread("王五", ticket).start();

	}
}
另外如果有多个售票员或者买票员,需要将Ticket.java中的notify改为notifyAll.否则可能导致程序运行达不到预期的效果,例如有两个售票员和一个买票员,假如其中的一个售票员和买票员都在wait,这个时候另外一个售票员放完票后调用notify唤醒的是在等待的售票员,这个时候由于有票,所以它也会wait,而买票员的画没有notify将其唤醒了。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值