当多个线程同时对共享资源进行访问时,可能会引发数据竞争和错误的结果。Java 提供了多种同步机制来避免这种情况,其中最常用的是互斥锁。在这个实战项目中,我们将实现一个卖票系统,并使用 Java 多线程和同步锁来确保多个线程同时访问同一资源的正确性。
需求描述
我们要实现一种买票系统,共有三个窗口,每个窗口可以同时售卖 100 张票。当所有的票都售出后,系统应该停止售票。同时,我们需要使用 Java 多线程和同步锁来确保卖票的正确性。
实现步骤
- 创建一个 Ticket 类,并在该类中定义一个变量作为票的数量,同时提供售票和查询余票的方法。
public class Ticket {
private int count;
public Ticket(int count) {
this.count = count;
}
public synchronized boolean sale() {
if (count > 0) {
count--;
return true;
} else {
return false;
}
}
public synchronized int getCount() {
return count;
}
}
在这个类中,我们使用 synchronized 关键字来保证同时只有一个线程可以访问卖票和查询余票的方法。这样,当多个线程同时访问 Ticket 类的方法时,就不会出现数据竞争问题。
- 创建一个窗口类 Window ,并在该类中定义卖票的方法。
public class Window implements Runnable {
private Ticket ticket;
public Window(Ticket ticket) {
this.ticket = ticket;
}
@Override
public void run() {
while (ticket.getCount() > 0) {
if (ticket.sale()) {
System.out.println(Thread.currentThread().getName() + " 卖了一张票,余票为:" + ticket.getCount());
}
}
}
}
在这个类中,我们实现了 Runnable 接口,并在 run 方法中循环售票,并打印出每次售票的信息。这里用 Ticket 类的 getCount 方法来判断是否还有票可售,同时使用 Ticket 类的 sale 方法来售卖票。
- 在主方法中创建三个线程,并分别启动这三个线程,让其同时执行。
public static void main(String[] args) {
Ticket ticket = new Ticket(100);
Window window1 = new Window(ticket);
Window window2 = new Window(ticket);
Window window3 = new Window(ticket);
Thread thread1 = new Thread(window1, "窗口1");
Thread thread2 = new Thread(window2, "窗口2");
Thread thread3 = new Thread(window3, "窗口3");
thread1.start();
thread2.start();
thread3.start();
}
在这个主方法中,我们创建了三个 Window 类的实例,并让这三个实例共享同一个 Ticket 类的实例。然后,我们将这三个实例分别作为参数创建了三个线程,并开启这三个线程,让其同时执行。
示例说明
示例 1:运行该程序,将会输出每次售票的信息,如下所示:
窗口1 卖了一张票,余票为:99
窗口2 卖了一张票,余票为:98
窗口3 卖了一张票,余票为:97
窗口1 卖了一张票,余票为:96
...
窗口3 卖了一张票,余票为:3
窗口3 卖了一张票,余票为:2
窗口3 卖了一张票,余票为:1
窗口3 卖了一张票,余票为:0
示例 2:假设我们将 Ticket 类的方法改成非同步方法,运行该程序,将会出现数据竞争问题,结果可能如下所示:
窗口1 卖了一张票,余票为:97
窗口2 卖了一张票,余票为:96
窗口1 卖了一张票,余票为:95
窗口2 卖了一张票,余票为:94
窗口3 卖了一张票,余票为:93
窗口2 卖了一张票,余票为:91
窗口1 卖了一张票,余票为:92
窗口2 卖了一张票,余票为:90
...
窗口2 卖了一张票,余票为:-3
窗口3 卖了一张票,余票为:-4
窗口1 卖了一张票,余票为:-5
从这个示例中可以看出,当多个线程同时访问 Ticket 类的方法时,就会出现数据竞争问题,导致程序出现错误的结果。
综上,本实战项目通过 Java 多线程和同步锁的应用,实现了多个线程同时访问共享资源的安全性控制。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程实现同步锁卖票实战项目 - Python技术站