Created
July 12, 2012 08:06
-
-
Save jamesmoriarty/3096576 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
: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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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