Рассмотрим приведенный ниже фрагмент. В нем я определяю один метод, называемый doit
, который впоследствии вызывается из двух разных потоков.Рубиновые потоки: методы и экземпляры объектов
В отличие от ожидаемого, t.object_id
в методе продолжает возвращать два разных идентификатора, как если бы вызов метода из каждого потока получил свое собственное пространство в памяти.
Что я ожидал, так это то, что во втором потоке, входящем в метод, он заменит ранее заданный хэш, в результате чего тот же самый идентификатор объекта будет напечатан в остальное время. Другими словами, я думал, что был бы один экземпляр Хэша.
Возможно, это предположило бы, что цикл в первой записи метода заблокировал бы любой последующий доступ к нему, но это, очевидно, не так.
Так что же такое сделка с методами? Каждый вызов из отдельного потока получает свою собственную копию в памяти? Каков правильный способ понять это?
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 вызовов DoIt имеют свое собственное пространство памяти в стеке. Если вы хотите, чтобы два потока работали на одном объекте, попробуйте передать аргумент методу. как doit (t) – GingerJim
@GingerJim - это не сработает, потому что ссылки параметров скопированы на локальные члены - 't = Hash.new' не изменит' t' в другом вызове функции. –