写一个Java多线程应用程序,模拟三个人排队买票,张三、李四和王五买电影票,售票员只有三张5元的钱,电影票5元一张。张某拿一张20的排在李某的前面买票,李某排在赵某的前面拿一张10元的人民币买票,赵某拿着一张5元的人民币在买票。
时间: 2024-12-01 15:19:09 浏览: 44
这是一个简单的Java多线程同步购买电影票的例子,我们将使用`Thread`, `wait()`, `notify()` 和 `synchronized` 关键字来实现并发控制:
```java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
class MovieTicket {
private int ticketCount = 3;
private int money = 15; // 售票员总金额
private ReentrantLock lock = new ReentrantLock();
private Condition hasTicket = lock.newCondition();
private Condition hasMoney = lock.newCondition();
public void sellTicket(String name) throws InterruptedException {
lock.lock();
try {
while (ticketCount == 0 || money < 5) {
if (money < 5) {
hasMoney.await(); // 等待有足够的钱
} else {
hasTicket.await(); // 等待有票
}
}
System.out.println(name + "正在购买电影票,还剩" + ticketCount + "张");
money -= 5;
ticketCount--;
if (ticketCount > 0) {
hasTicket.signal(); // 售出一张票,唤醒等待者
}
} finally {
lock.unlock();
}
}
public synchronized void refund(int amount) {
money += amount;
if (money >= 5 && ticketCount > 0) {
hasTicket.signal(); // 如果有钱且还有票,通知等待买票的人
}
hasMoney.signal(); // 总金额足够了,让下一个买家过来
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MovieTicket ticket = new MovieTicket();
Thread t1 = new Thread(() -> ticket.sellTicket("张三"));
Thread t2 = new Thread(() -> ticket.sellTicket("李四"));
Thread t3 = new Thread(() -> ticket.sellTicket("王五"));
t1.start();
t2.start();
t3.start();
Thread.sleep(100); // 张某先交20元
ticket.refund(15); // 售票员找回15元
t2.start(); // 李某继续购票
Thread.sleep(100); // 李某交10元
ticket.refund(5); // 售票员退款5元
t3.start(); // 赵某购票
}
}
```
在这个例子中,我们创建了一个MovieTicket类代表售票处,使用了两个Condition对象hasTicket和hasMoney来控制何时可以卖出票或收取更多的钱。通过`synchronized`关键字保证了对共享资源的互斥访问。
每个线程都尝试直接调用sellTicket方法,如果当前无票或钱不足,则会进入相应的条件状态并等待。当满足条件后,它们会继续执行购票操作,然后更新售票员的状态。
阅读全文