一、实验目的
1、掌握多线程的创建方法;
2、掌握多线程的互斥与同步。
二、实验环境
Windows,IDEA。
三、实验内容
假设有100张火车票,创建10个线程模拟10个售票点,每个售票点100毫秒卖一张票,打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。
四、完成情况
五、源代码
(1)下面是一个简单的 Java 程序,演示了如何创建多个线程模拟售票点,并使用 synchronized
关键字确保同一张票只能被卖出一次。
TicketBox 类:totalTickets: 表示总共的票数。
构造方法用于初始化票箱,接收一个初始的总票数。
sellTicket(String sellerName): 使用 synchronized 关键字确保同一时刻只有一个线程能够访问该方法。在方法中,检查是否还有余票,如果有,模拟售票过程,打印卖票信息,并返回 true;如果票已售完,打印相应信息并返回 false。
package com;
class TicketBox {
private int totalTickets;
public TicketBox(int totalTickets) {
this.totalTickets = totalTickets;
}
// 使用 synchronized 关键字确保同一时刻只有一个线程能够访问该方法
public synchronized boolean sellTicket(String sellerName) {
if (totalTickets > 0) {
// 模拟售票过程
System.out.println(sellerName + " 卖出一张票,剩余票数:" + (--totalTickets));
return true;
} else {
System.out.println(sellerName + " 票已售完,无法卖出。");
return false;
}
}
}
TicketSeller 类:name: 表示售票点的名称。
ticketBox: 表示售票点所属的票箱。
构造方法用于初始化售票点,接收售票点的名称和所属的票箱。
实现 Runnable 接口的 run 方法,用于模拟售票过程。在方法中,循环卖票,每张票耗时100毫秒。在卖票的过程中,调用 TicketBox 的 sellTicket 方法进行实际的售票操作。
package com;
class TicketSeller implements Runnable {
private String name;
private TicketBox ticketBox;
public TicketSeller(String name, TicketBox ticketBox) {
this.name = name;
this.ticketBox = ticketBox;
}
@Override
public void run() {
// 模拟售票过程,每个售票点卖100张票,每张票耗时100毫秒
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 调用 TicketBox 的 sellTicket 方法售票
if (!ticketBox.sellTicket(name)) {
break; // 如果票已售完,退出循环
}
}
}
}
TicketSellingSimulation 类:
main 方法:创建一个共享的票箱 TicketBox 对象,设置初始总票数为 100。
创建10个售票点线程,每个线程都是一个 TicketSeller 对象,共享同一个票箱。线程启动后,会模拟售票过程。
package com.wzh;
public class TicketSellingSimulation {
public static void main(String[] args) {
// 设置控制台字符集为 UTF-8
System.setProperty("console.encoding", "UTF-8");
// 创建共享的票数
TicketBox ticketBox = new TicketBox(100);
// 创建10个售票点线程
for (int i = 1; i <= 10; i++) {
new Thread(new TicketSeller("售票点 " + i, ticketBox)).start();
}
}
}