代码之家  ›  专栏  ›  技术社区  ›  Zombies

ruby是否具有synchronize关键字的Java等价物?

  •  11
  • Zombies  · 技术社区  · 15 年前

    ruby是否具有synchronize关键字的Java等价物?我使用的是1.9.1,我并不认为有一种优雅的方法可以做到这一点。

    2 回复  |  直到 15 年前
        1
  •  15
  •   Chris Bunch    15 年前

    它没有 synchronize 关键字,但您可以通过 Monitor

    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
    
        2
  •  12
  •   Community Mohan Dere    5 年前

    公认的答案并不代表 synchronize 作品!

    你可以直接说出来 synchronize do 200_000

    所以,这里有一个例子,来说明使用/不使用 使同步

    非线程安全示例:

    #! /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 .

    这里发生了什么?

    当线程启动时,它们会看到 . 但当他们每个人 ,由于并行计算,数值变得不同。如果没有适当的同步,系统的部分状态 是不可预测的。

    现在我们称之为这些行动 原子的 :

    #! /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
    

    现在,通过使用 布洛克,我们保证 原子性 添加操作的。

    但是线程仍然以随机顺序运行(1->0->2)

    this article .

    推荐文章