文章会有【原创】或者【转载】标示,部分来自Google Baidu的学习结果 {Java/PHP/Python/Ruby/Go}

Ruby 多线程学习【转载】  


文章转载自http://www.ways2u.com/knowledge/?post=54

Monitor 是一种资源互斥访问的解决方案。它提供了一种机制,以供不同线程互斥访问指定的共享资源。

我们可以通过使用继承 Monitor 类解决上一节的问题。

 

require 'monitor'

 

class Counter < Monitor

        attr_reader :number

 

       def initialize

           @number = 0

           super # 初始化父类数据

       end

 

        def plus

           synchronize do

              @number += 1

           end

       end

end

 

c = Counter.new

 

t1 = Thread.new { 10000.times { c.plus } }

t2 = Thread.new { 10000.times { c.plus } }

 

t1.join

t2.join

 

puts c.number

 

执行结果为:

20000

 

可以看到,继承 Monitor 类后,我们可以使用 synchronize 方法,对于一个 Monitor 类的实例,同时只能有一个线程执行 synchronize 代码块的操作。代码的执行结果为“ 20000 ”,和我们期望的一致。

 

如果不想使 Monitor 成为自己类的父类,也可以使用 MonitorMixin 模块。

 

require 'monitor'

 

class Counter

    include MonitorMixin

 

    attr_reader :number

 

       def initialize

           @number = 0

           super

       end

 

        def plus

           synchronize do

              @number += 1

           end

       end

end

 

c = Counter.new

 

t1 = Thread.new { 10000.times { c.plus } }

t2 = Thread.new { 10000.times { c.plus } }

 

t1.join

t2.join

 

puts c.number

 

执行结果为:

20000

 

也可以单独使用 Monitor 类的实例对象来完成同步操作。

 

require 'monitor'

 

class Counter

       attr_reader :number

 

       def initialize

           @number = 0

           super

       end

 

        def plus

           @number += 1

       end

end

 

c = Counter.new

lock = Monitor.new

 

t1 = Thread.new { 10000.times { lock.synchronize{ c.plus } } }

t2 = Thread.new { 10000.times { lock.synchronize{ c.plus } } }

 

t1.join

t2.join

 

puts c.number

 

执行结果为

20000

 

也可以将使用 extend 方法将 Monitor 模块的方法引入完成同步操作。

 

require 'monitor'

 

class Counter

       attr_reader :number

 

       def initialize

           @number = 0

           super

       end

 

        def plus

           @number += 1

       end

end

 

c = Counter.new

c.extend(MonitorMixin)

 

t1 = Thread.new { 10000.times { c.synchronize{ c.plus } } }

t2 = Thread.new { 10000.times { c.synchronize{ c.plus } } }

 

t1.join

t2.join

 

puts c.number