线程同步使用条件变量(Condition Variables)
require 'monitor'
SONGS = [
'Blue Suede Shoes',
'Take Five',
'Bye Bye Love',
'Rock Around The Clock',
'Ruby Tuesday'
]
START_TIME = Time.new
def timestamp
(Time.now - START_TIME).to_i
end
# Wait for up to two minutee between customer requests
def get_customer_request
sleep(120 * rand)
song = SONGS.shift
puts "#{timestamp}: Requesting #{song}" if song
song
end
# Songs take between two and three minutes
def play(song)
puts "#{timestamp}: Playing #{song}"
sleep(120 + 60*rand)
end
ok_to_shutdown = false
# and here's our original code
playlist = []
playlist.extend(MonitorMixin)
plays_pending = playlist.new_cond
# Customer request thread
customer = Thread.new do
loop do
req = get_customer_request
puts req
break unless req
playlist.synchronize do
playlist << req
plays_pending.signal
end
end
end
# Player Thread
player = Thread.new do
loop do
song = nil
playlist.synchronize do
break if ok_to_shutdown && playlist.empty?
plays_pending.wait_while {playlist.empty?}
song = playlist.shift
end
break unless song
play(song)
end
end
customer.join
ok_to_shutdown = true
player.join
19: Requesting Blue Suede Shoes
Blue Suede Shoes
19: Playing Blue Suede Shoes
63: Requesting Take Five
Take Five
101: Requesting Bye Bye Love
Bye Bye Love
149: Playing Take Five
169: Requesting Rock Around The Clock
Rock Around The Clock
215: Requesting Ruby Tuesday
Ruby Tuesday
269: Playing Bye Bye Love
428: Playing Rock Around The Clock
574: Playing Ruby Tuesday