1

如果要锁定实例上的方法,则必须Mutex为每个实例和方法创建一个:

class Foo
  def initialize
    @blue_mutex = Mutex.new
    @red_mutex = Mutex.new
  end

  def blue
    @blue || @blue_mutex.synchronize do
      @blue ||= Blue.new
    end
  end

  def red_mutex
    @red || @red_mutex.synchronize do
      @red ||= Red.new
    end
  end
end

接受参数是否存在逻辑错误Thread.exclusive

class Foo
  def blue
    @blue || Thread.exclusive("#{object_id}/blue") do
      @blue ||= Blue.new
    end
  end

  def red
    @red || Thread.exclusive("#{object_id}/red") do
      @red ||= Red.new
    end
  end
end

Thread.exclusive如果可以只接受一个定义排他性范围的参数,为什么要创建互斥锁?

4

1 回答 1

0

简短的回答是 API 可以按照您描述的方式完成。事实上,这就是Java通过让您锁定任意对象所做的事情。它必须耍花招,因为锁的跟踪会占用对象本身的一些保留空间。此外,当对象被锁定并成为竞争对象时,必须创建一个真正的互斥体,这会占用更多空间。但希望您的代码没有被锁定和解锁的对象乱扔垃圾。我的猜测是 Ruby 的创建者不想让每个对象都负担这些额外的功能,而这些功能只会不经常使用。

我在上面假设当您说“笨拙”时,您指的是代码的可读性。如果您担心性能,我怀疑会有很大差异。在幕后,任何一种方法都可以使用相同的、非常有效的技术。这只是在每个对象上存储薄锁的额外内存的问题。我在这里发现了一些有趣的细节

于 2012-06-09T00:00:52.027 回答