[面试Java]线程同步之Java多线程实现多窗口售票程序

导言

线程同步Java高并发的核心内容之一,线程同步目的是保证多线程以安全的方式按照一定的次序执行以满足对互斥资源的请求,从而协作完成某项任务,其重点是保证线程安全

所谓线程安全,是多线程操纵共享数据的时候,对共享数据的操作不会出现丢失修改脏数据等问题,或出现由于不满足可见性原子性有序性而产生的问题。例如,线程A让计数器counter的值加1的同时线程B让计数器加1,这就造成了丢失修改,与我们原本的目的向背驰:多线程对共享数据——计数器变量counter的修改应该排队进行。

这里先不讨论丢失修改脏数据以及可见性等问题,因为这些是Java高并发的永恒主题,在以后的博客当中,一定会进行深入地讨论。

多窗口售票

多窗口售票是一个入门级别的线程同步案例,也是线程同步和线程安全的重要应用,有助于理解多线程的原子性、可见性等问题。

多窗口售票的需求描述:

利用多线程模拟3个窗口售出300张票,三个窗口同时售票(注意:同时指同一时间段,因此是并发的意思,不是并行),需要保证三个窗口不能出现错票重票漏票的问题。

需求分析:

  1. 多线程同步,一定存在共享数据,在这个案例当中,共享数据就是一定数量的票,可以用一个静态变量表示,或者用同一个以票数为属性的对象表示。
  2. 对共享数据的操作需要保证互斥,因此必须使用,我们选择synchronized来保证互斥访问共享数据,锁住的对象是可以是唯一的共享数据,或者其他唯一的对象也可以。
  3. 多线程的实现方式有多种,我们尝试其中两种:继承Thread类实现Runnable接口

方式一:继承Thread类

继承Thread类实现多线程的步骤是:

  1. 继承Thread类,重写run()方法
  2. 创建子类对象,调用start()方法启动子线程

每个窗口对应一个线程,因此需要一个线程类。在这个线程类当中,需要一个静态变量表示多个线程的共享资源,即剩余票数。另外,可以给每个窗口一个独特的窗口名字,用普通的属性即可。

代码如下:

package com.java.www.day20210102;

/**
 * 每个窗口代表1个线程,因此我们定义窗口类作为Thread的子类
 * */
class WindowThread extends Thread{
   

    /**静态变量是类变量,因此可以作为多个对象的共享数据,并进行初始化*/
    private static int ticketNumber = 300;
    /**窗口名称*/
    private String windowName;

    /**在构造方法当中传入窗口名称*/
    public WindowThread(String windowName){
   
        this.windowName = windowName;
    }

    /**重写run()方法*/
    @Override
    public void run() {
   
        while (true){
   
            // 每次循环都准备获取票号,获取之前都要先获取锁,锁只要是唯一的就可以(
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值