我只是想知道类实例变量是否是线程安全的。最近,我遇到了一个由自定义 ORM 模型引起的数据库锁定问题。(反正没有活动记录或续集模型,只是我自己创建的 ORM 的简单版本)。
为了简单起见,我只是在这里包装了一个简单的版本:
我使用一个简单的类实例变量来保存一个数据库实例(可能是一个 Sequel::Database 对象)。
class TestORM
class << self
attr_accessor :db
def self.db=( db )
@db = db
end
end
end
我为它创建了一个测试脚本来验证这个数据库是否是线程安全的。
require 'test_orm.rb'
t1 = Thread.new do
db = 'db string 1'
p "Thread 1: before assign, thread = #{Thread.current.object_id}, TestORM.db.object_id = #{TestORM.db.object_id}"
TestORM.db = db
p "Thread 1: after assign, thread = #{Thread.current.object_id}, TestORM.db.object_id = #{TestORM.db.object_id}"
sleep( 0.5 )
p "Thread 1: TestORM.db.object_id = #{TestORM.db.object_id}"
end
t2 = Thread.new do
db = 'db string 2'
p "Thread 2: before assign, thread = #{Thread.current.object_id}, TestORM.db.object_id = #{TestORM.db.object_id}"
TestORM.db = db
p "Thread 2: after assign, thread = #{Thread.current.object_id}, TestORM.db.object_id = #{TestORM.db.object_id}"
sleep( 0.5 )
p "Thread 2: TestORM.db.object_id = #{TestORM.db.object_id}"
end
t1.join
t2.join
运行上面的代码产生以下结果:
"Thread 1: before assign, thread = 70332471940100, TestORM.db.object_id = 4"
"Thread 2: before assign, thread = 70332471939980, TestORM.db.object_id = 4"
"Thread 1: after assign, thread = 70332471940100, TestORM.db.object_id = 70332471939840"
"Thread 2: after assign, thread = 70332471939980, TestORM.db.object_id = 70332471939520"
"Thread 1: TestORM.db.object_id = 70332471939520"
"Thread 2: TestORM.db.object_id = 70332471939520"
从上面的结果来看,似乎类实例变量不是线程安全的,因为线程 2 覆盖了线程 1 的 TestORM.db 实例。
关于这种包装的任何提示或任何解决方案?
红宝石版本:红宝石1.9.2p320