售票pv操作java实现_Java多线程实现火车站售票案例

需求:

火车站有5个窗口,有1000张火车票,同时开始售票,请用Java多线程实现

分析:

这是学习Java多线程的时候必定会遇到的一个案例

窗口一共有五个,共同操作1000张票,多以票需要定义成静态的

线程在操作的数据的时候,我们要注意数据的安全,可以使用同步代码块或同步方法,也可以通过加一锁(ReentrantLock)的方式来解决,下面我们编写代码来演示。

第一种方式:使用同步代码块+锁

package com.qf.demos;public class Demo08 {public static void main(String[] args) {// 创建Runnable,记住只需创建一次TicketRunnable tr = new TicketRunnable();// 创建线程对象Thread t1 = new Thread(tr,"1号窗口");    Thread t2 = new Thread(tr,"2号窗口");    Thread t3 = new Thread(tr,"3号窗口");    Thread t4 = new Thread(tr,"4号窗口");    Thread t5 = new Thread(tr,"5号窗口");    // 开启线程    t1.start();    t2.start();    t3.start();    t4.start();    t5.start();}}class TicketRunnable implements Runnable{   // 静态的tickets,只有一份,所有线程都操作这个数据    private static int tickets = 1000;        // 静态的lock,只在内存中存在一份    private static Object lock = new Object();        @Override    public void run() {        while(true){        // 同步代码块,保障线程操作数据的安全            synchronized (lock) {// 这里的锁对象我们使用的是静态的lock,只在内存中存在一份            // 再次进行判断,防止出现负值                if(tickets <= 0){                    break;                }                try{                    Thread.sleep(10);                } catch(InterruptedException e){                    e.printStackTrace();                }                // 每执行一次相当于卖掉一张票,tickets减少1                tickets--;                System.out.println(Thread.currentThread().getName() + "...卖出了第" + (1000 - tickets) + "号票,还剩下" + tickets + "张票.......");            }        }    }}

运行结果:

00d41f3720ddb702b46ea3bcec3343fb.png

第二种方式:使用ReentrantLock(可重入锁)

ReentrantLock是独占锁,加锁和解锁的过程需要手动进行,不易操作,但非常灵活。

ReentrantLock可重入,但加锁和解锁需要手动进行,且次数需一样,否则其他线程无法获得锁。

package com.qf.demos;import java.util.concurrent.locks.ReentrantLock;public class Demo07 {public static void main(String[] args) {// 创建Runnable,记住只需创建一次TicketRunnable tr = new TicketRunnable();// 创建线程对象Thread t1 = new Thread(tr,"1号窗口");    Thread t2 = new Thread(tr,"2号窗口");    Thread t3 = new Thread(tr,"3号窗口");    Thread t4 = new Thread(tr,"4号窗口");    Thread t5 = new Thread(tr,"5号窗口");    // 开启线程    t1.start();    t2.start();    t3.start();    t4.start();    t5.start();}}class TicketRunnable implements Runnable{// 静态的tickets,只有一份,所有线程都操作这个数据    private static int tickets = 1000;        // 静态的lock,只在内存中存在一份static ReentrantLock lock = new ReentrantLock();@Overridepublic void run() {// 再次进行判断,防止出现负值while(tickets > 0) {// 每一条线程执行的时候都上锁,结束的时候解锁,保证只能有一条线程执行下面的代码lock.lock();if (tickets>0) {// 每执行一次相当于卖掉一张票,tickets减少1tickets--;System.out.println(Thread.currentThread().getName() + "正在销售第" + (1000 - tickets) + "张票");}// 解锁lock.unlock();}}}

运行结果:

dbddc053aab8aff7cd6d8768a9e58bd9.png

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值