ruby には synchronize キーワードに相当する Java がありますか? 私は 1.9.1 を使用していますが、これを行うエレガントな方法がよくわかりません。
4059 次
2 に答える
16
キーワードはありませんが、クラスsynchronize
を介して非常によく似たものを取得できます。Monitor
以下は、プログラミング Ruby 1.8 ブックの例です。
require 'monitor'
class Counter < Monitor
attr_reader :count
def initialize
@count = 0
super
end
def tick
synchronize do
@count += 1
end
end
end
c = Counter.new
t1 = Thread.new { 100_000.times { c.tick } }
t2 = Thread.new { 100_000.times { c.tick } }
t1.join; t2.join
c.count → 200000
于 2010-07-08T22:32:59.657 に答える
14
受け入れられた答えは、どのように機能するかを表していませんsynchronize
!
コメントアウトしてsynchronize do
、受け入れられた回答のスクリプトを実行するだけです-出力は同じになります: 200_000
!
synchronize
したがって、ブロックあり/なしの実行の違いを示す例を次に示します。
スレッドセーフではない例:
#! /usr/bin/env ruby
require 'monitor'
class Counter < Monitor
attr_reader :count
def initialize
@count = 0
super
end
def tick i
puts "before (#{ i }): #{ @count }"
@count += 1
puts "after (#{ i }): #{ @count }"
end
end
c = Counter.new
3.times.map do |i|
Thread.new do
c.tick i
end
end.each(&:join)
puts c.count
出力では、次のようなものが得られます。
before (1): 0
after (1): 1
before (2): 0
before (0): 0 <- !!
after (2): 2
after (0): 3 <- !!
Total: 3
スレッド(0)
が開始されたとき、count
は と等しかった0
が、追加後+1
の値は でした3
。
そこで何が起こるの?
スレッドが開始されると、初期値の が表示されcount
ます。しかし、それぞれを加算しようとする+1
と、並列計算の結果、値が異なってしまいました。適切な同期がないと、 の部分的な状態count
は予測できません。
原子性
これらの操作をアトミックと呼びます:
#! /usr/bin/env ruby
require 'monitor'
class Counter < Monitor
attr_reader :count
def initialize
@count = 0
super
end
def tick i
synchronize do
puts "before (#{ i }): #{ @count }"
@count += 1
puts "after (#{ i }): #{ @count }"
end
end
end
c = Counter.new
3.times.map do |i|
Thread.new do
c.tick i
end
end.each(&:join)
puts c.count
出力:
before (1): 0
after (1): 1
before (0): 1
after (0): 2
before (2): 2
after (2): 3
Total: 3
ここで、synchronize
ブロックを使用して、追加操作の原子性を確保します。
ただし、スレッドは引き続きランダムな順序で実行されます (1->0->2)
詳細な説明については、この記事を読み続けることができます。
于 2015-06-15T08:14:42.840 に答える