logo
Программирование на языке Ruby

Листинг 13.5. Реализация класса Queue с помощью монитора

# Автор: Shugo Maeda

require 'monitor'

class Queue

 def initialize

  @que = []

  @monitor = Monitor.new

  @empty_cond = @monitor.new_cond

 end

 def enq(obj)

  @monitor.synchronize do

   @que.push(obj)

   @empty_cond.signal

  end

 end

 def deq

  @monitor.synchronize do

   while @que.empty?

    @empty_cond.wait

   end

   return @que.shift

  end

 end

end

class SizedQueue < Queue

 attr :max

 def initialize(max)

  super()

  @max = max

  @full_cond = @monitor.new_cond

 end

 def enq(obj)

  @monitor.synchronize do

   while @que.length >= @max

    @full_cond.wait

   end

   super(obj)

  end

 end

 def deq

  @monitor.synchronize do

   obj = super

   if @que.length < @max

    @full_cond.signal

   end

   return obj

  end

 end

 def max=(max)

  @monitor.synchronize do

   @max = max

   @full_cond.broadcast

  end

 end

end

Еще один вариант синхронизации (двузначную блокировку со счетчиком) предлагает библиотека sync.rb. В ней определен модуль Sync_m, который можно применять вместе с ключевыми словами include и extend (как и Mutex_m). Этот модуль содержит методы locked?, shared?, exclusive?, lock, unlock и try_lock.