Примеры 2 и 3 абсолютно одинаковы.Модули и классы также являются объектами, и определение одноэлементного метода для объекта фактически определяет его для его одноэлементного класса.потокобезопасны.Пример 1 также должен быть поточно-ориентированным, но он уступает двум другим, поскольку требует синхронизации переменных вручную.
Однако, если вам нужно воспользоваться тем фактом, что переменные класса совместно используются в дереве наследования,возможно, вам придется использовать первый подход.
Безопасность потоков, присущая языку Ruby, зависит от реализации.
MRI до 1.9, реализованные потоки на виртуальной машинеуровень .Это означает, что, хотя Ruby способен планировать выполнение кода, на самом деле ничто не запускает параллельно в рамках одного процесса Ruby.Ruby 1.9 использует собственные потоки, синхронизированные с глобальной блокировкой интерпретатора .Только контекст, который содержит блокировку, может выполнять код.
n, x = 10, 0
n.times do
Thread.new do
n.times do
x += 1
end
end
end
sleep 1
puts x
# 100
Значение x
равно , всегда , согласованному в MRI.На JRuby, однако, картина меняется.Многократное выполнение одного и того же алгоритма давало значения 76
, 87
, 98
, 88
, 94
.Результатом может быть что угодно, потому что JRuby использует потоки Java, которые являются реальными потоками и выполняются параллельно.
Как и в языке Java, для безопасного использования потоков в JRuby требуется ручная синхронизация.Следующий код всегда приводит к согласованным значениям для x
:
require 'thread'
n, x, mutex = 10, 0, Mutex.new
n.times do
Thread.new do
n.times do
mutex.synchronize do
x += 1
end
end
end
end
sleep 1
puts x
# 100