O'Reilly logo

Ruby Cookbook by Leonard Richardson, Lucas Carlson

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

20.4. Synchronizing Access to an Object

Problem

You want to make an object accessible from only one thread at a time.

Solution

Give the object a Mutex member (a semaphore that controls whose turn it is to use the object). You can then use this to synchronize activity on the object.

This code gives every object a synchronize method. This simulates the behavior of Java, in which synchronize is a keyword that can be applied to any object:

	require 'thread'
	class Object
	  def synchronize
	    mutex.synchronize { yield self }
	  end

	  def mutex
	    @mutex ||= Mutex.new
	  end
	end

Here's an example. The first thread gets a lock on the list and then dawdles for a while. The second thread is ready from the start to add to the list, but it doesn't get a chance until the first thread releases the lock.

	list = []
	Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }
	Thread.new { list.synchronize { |l| 3.times { l.push "Thread 2" } } }
	sleep(6)
	list
	# => ["Thread 1", "Thread 1", "Thread 1", "Thread 2", "Thread 2", "Thread 2"]

Object#synchronize only prevents two synchronized code blocks from running at the same time. Nothing prevents a wayward thread from modifying the object without calling synchronize first:

	list = []
	Thread.new { list.synchronize { |l| sleep(5); 3.times { l.push "Thread 1" } } }
	Thread.new { 3.times { list.push "Thread 2" } }
	sleep(6)
	list
	# => ["Thread 2", "Thread 2", "Thread 2", "Thread 1", "Thread 1", "Thread 1"]

Discussion

One of the big advantages of multithreaded ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required