Single Threaded Execution

 require 'thread'
 
 class Client
   def initialize(gate, name)
     @gate = gate
     @name = name
     @t = Thread.new {
       do_run
     }
   end
   
   def do_run
     3.times do
       @gate.pass(@name)
     end
   end
   
   def join
     @t.join
   end
 end
 
 class Gate
   def initialize
     @counter = 0
     @mutex = Mutex.new
   end

   def pass(name)     
     @mutex.synchronize {
       puts "----"
       @counter += 1
       puts "#{@counter} enter #{name}"
       2.times do
         print "."
         sleep 1
       end
       puts "\n#{@counter} exit  #{name}"
       puts "----"
     }
   end
 end
 
 # Main
 gate = Gate.new
 c1 = Client.new(gate, "Aclient")
 c2 = Client.new(gate, "Bclient")
 c3 = Client.new(gate, "Cclient")
 
 c1.join
 c2.join
 c3.join
      • -
1 enter Aclient .. 1 exit Aclient
      • -
      • -
2 enter Bclient .. 2 exit Bclient
      • -
      • -
3 enter Cclient .. 3 exit Cclient
      • -
      • -
4 enter Aclient .. 4 exit Aclient
      • -
      • -
5 enter Bclient .. 5 exit Bclient
      • -
      • -
6 enter Cclient .. 6 exit Cclient
      • -
      • -
7 enter Aclient .. 7 exit Aclient
      • -
      • -
8 enter Bclient .. 8 exit Bclient
      • -
      • -
9 enter Cclient .. 9 exit Cclient
      • -