ruby是否具有Java等效的synchronize关键字?
ruby是否具有Java等效的synchronize关键字? 我使用的是1.9.1,我不太看到这样做的优雅方式。
它没有synchronize
关键字,但您可以通过Monitor
类获得非常相似的内容。 这是Programming 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
接受的答案并不代表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
状态是不可预测的。
primefaces性
现在我们称这些操作是primefaces的 :
#! /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
块,我们确保了add操作的primefaces性 。
但线程仍按随机顺序运行(1-> 0-> 2)
有关详细说明,您可以继续阅读本文 。