Ruby线程:对象的方法和实例

时间:2014-03-18 12:18:48

标签: ruby multithreading

考虑下面的代码段。在其中,我定义了一个名为doit的方法,随后从两个不同的线程调用。

与我的预期相反,方法中的t.object_id会不断返回两个不同的ID,就好像每个线程对方法的调用在内存中都有自己的空间一样。

我期望发生的是,在进入该方法的第二个线程上,它将替换先前定义的哈希值,导致在其余时间打印相同的对象ID。换句话说,我认为会有一个Hash的实例。

可以说,这可能表明方法的第一个条目中的循环会阻止对其的任何后续访问,但显然情况并非如此。

那么方法的处理是什么?来自单独线程的每次调用是否在内存中都有自己的副本?理解这个的正确方法是什么?

def doit
    t = Hash.new
    puts t.object_id
    loop do
      sleep 1
      puts t.object_id
    end
end

t1 = Thread.new { doit }
t2 = Thread.new { doit }

t1.join
t2.join

举例来说,这是输出:

21329316
21327684
21329316
21327684
21329316
21327684
21327684
21329316
21327684
21329316
21327684
21329316

2 个答案:

答案 0 :(得分:2)

tdoit的局部变量,仅在方法的范围中声明。每次执行都会收到自己的t

如果您要分享 t,请将其声明为实例成员@t

def doit
    @t = Hash.new
    puts @t.object_id
    loop do
      sleep 1
      puts @t.object_id
    end
end

t1 = Thread.new { doit }
t2 = Thread.new { doit }

t1.join
t2.join

现在你的输出看起来像这样:

15223760
15223580
15223580
15223580
15223580
15223580
15223580
15223580
15223580
15223580
15223580

答案 1 :(得分:1)

线程与它无关。 t是每次调用doit时初始化的局部变量 - 因此每次调用都会获得自己的t。请注意,删除线程会产生相同的结果,尽管不是交错的:

def doit
  t = Hash.new
  t.object_id
end

doit #=> 21329316
doit #=> 21327684