You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby并发实现:多线程访问共享资源及内存级电影座位预订方案

Ruby并发与共享资源处理

1. Ruby中实现并发及共享资源处理

Ruby中实现并发最常用的方式是使用线程(Thread),处理多线程访问共享资源的核心是通过同步机制避免竞态条件。常见的同步工具包括:

  • Mutex(互斥锁):最基础的同步原语,同一时间只允许一个线程持有锁进入临界区。
  • Monitor:Ruby的Object类默认混入MonitorMixin,可直接用mon_synchronize方法封装互斥锁逻辑。
  • ConditionVariable:配合锁使用,用于线程间的等待/通知场景。

示例:用Mutex保护共享计数器

require 'thread'

counter = 0
mutex = Mutex.new

10.times.map do
  Thread.new do
    1000.times do
      mutex.synchronize do
        counter += 1
      end
    end
  end
end.each(&:join)

puts counter # 稳定输出10000,无竞态条件

2. 内存实现电影座位预订及应用层校验

内存数据结构实现方案

用Hash存储座位状态(键为座位号,值为true已预订/false可预订),配合Mutex确保线程安全的读写操作,避免多个线程同时修改同一座位状态。

完整示例代码

require 'thread'

class MovieSeatBooking
  def initialize(total_seats = 100)
    @seats = (1..total_seats).to_h { |num| [num, false] }
    @mutex = Mutex.new
  end

  # 预订座位,返回是否成功
  def book_seat(seat_number)
    @mutex.synchronize do
      return false unless @seats.key?(seat_number) && !@seats[seat_number]
      @seats[seat_number] = true
      true
    end
  end

  # 查询座位状态
  def seat_available?(seat_number)
    @mutex.synchronize do
      @seats.key?(seat_number) && !@seats[seat_number]
    end
  end
end

# 模拟并发预订测试
booking_system = MovieSeatBooking.new(10)

20.times.map do
  Thread.new do
    seat = rand(1..10)
    success = booking_system.book_seat(seat)
    puts "线程#{Thread.current.object_id}预订座位#{seat}:#{success ? '成功' : '失败(已被预订/不存在)'}"
  end
end.each(&:join)

其他应用层校验方式

除了基于互斥锁的悲观锁方式,还可以使用:

  • 乐观锁(版本号机制):给每个座位绑定版本号,预订时先读取当前版本号和座位状态,修改前校验版本号是否一致,一致则更新版本号和座位状态,否则重试。
    class OptimisticMovieBooking
      def initialize(total_seats = 100)
        @seats = (1..total_seats).to_h { |num| [num, { available: true, version: 0 }] }
        @mutex = Mutex.new # 确保版本号与状态更新的原子性
      end
    
      def book_seat(seat_number)
        @mutex.synchronize do
          seat = @seats[seat_number]
          return false unless seat && seat[:available]
          
          current_version = seat[:version]
          seat[:available] = false
          seat[:version] = current_version + 1
          true
        end
      end
    end
    
  • CAS(比较并交换)操作:借助atomic gem提供的原子变量,对座位状态或版本号进行原子更新,减少显式锁的使用。复杂场景下仍需结合逻辑校验,确保预订操作的正确性。

内容的提问来源于stack exchange,提问作者shubham saxena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:55:22