Skip to content

Instantly share code, notes, and snippets.

@jamesmoriarty
Created July 12, 2012 08:06
Show Gist options
  • Save jamesmoriarty/3096576 to your computer and use it in GitHub Desktop.
Save jamesmoriarty/3096576 to your computer and use it in GitHub Desktop.
class Account
attr_reader :balance
def initialize(balance)
@balance = balance
end
def receive(amount)
@balance += amount
end
def transfer1(account_to, amount)
if (@balance - amount) < 0
raise "You do not have enough money."
else
sleep 1
@balance -= amount
account_to.receive(amount)
end
end
def transfer2(account_to, amount)
Thread.exclusive do
if (@balance - amount) < 0
raise "You do not have enough money."
else
sleep 1
@balance -= amount
account_to.receive(amount)
end
end
end
require "thread"
def transfer3(account_to, amount)
@semaphore ||= Mutex.new
@semaphore.synchronize do
if (@balance - amount) < 0
raise "You do not have enough money."
else
sleep 1
@balance -= amount
account_to.receive(amount)
end
end
end
end
:w ! ruby
Loaded suite -
Started
F..
Finished in 3.005404 seconds.
1) Failure:
test_transfer1(TestThreads) [-:66]:
<1> expected but was
<-98>.
3 tests, 5 assertions, 1 failures, 0 errors, 0 skips
require "test/unit"
class TestThreads < Test::Unit::TestCase
def setup
@account_from = Account.new 100
@account_to = Account.new 0
@amount = 99
end
def test_transfer1
threads = []
threads << Thread.new { @account_from.transfer1(@account_to, @amount) }
threads << Thread.new { @account_from.transfer1(@account_to, @amount) }
threads.each(&:join)
assert_equal 1, @account_from.balance
end
def test_transfer2
threads = []
threads << Thread.new { @account_from.transfer2(@account_to, @amount) }
threads << Thread.new { @account_from.transfer2(@account_to, @amount) }
assert_raise RuntimeError do
threads.each(&:join)
end
assert_equal 1, @account_from.balance
end
def test_transfer3
threads = []
threads << Thread.new { @account_from.transfer3(@account_to, @amount) }
threads << Thread.new { @account_from.transfer3(@account_to, @amount) }
assert_raise RuntimeError do
threads.each(&:join)
end
assert_equal 1, @account_from.balance
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment