# Question on threads

**URL:** <https://www.ruby-forum.com/t/question-on-threads/184824>\
**Category:** Ruby\
**Created:** [March 9, 2010, 5:40am UTC](https://www.ruby-forum.com/t/question-on-threads/184824 "2010-03-09T05:40:45Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jean\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@Jean\_G](https://www.ruby-forum.com/u/Jean_G)\
**Post date:** [March 9, 2010, 5:40am UTC](https://www.ruby-forum.com/t/question-on-threads/184824/1 "2010-03-09T05:40:45Z")

</div>

Hello,

count = 0  
threads = []

10.times do |i|  
threads[i] = Thread.new do  
sleep(rand(0.1))  
Thread.current[“mycount”] = count  
count += 1  
end  
end

threads.each {|t| t.join; print t[“mycount”], ", " }

For the code above, why the output numbers are random, rather than  
from 0 to 9 by increasing?

Thanks.

---

<div class="post-metadata">

**Author:** ![Jean\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@Jean\_G](https://www.ruby-forum.com/u/Jean_G)\
**Post date:** [March 9, 2010, 9:12am UTC](https://www.ruby-forum.com/t/question-on-threads/184824/2 "2010-03-09T09:12:34Z")

</div>

2010/3/9 Jean G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> end  
> end
> 
> threads.each {|t| t.join; print t[“mycount”], ", " }
> 
> For the code above, why the output numbers are random, rather than  
> from 0 to 9 by increasing?

Because there are no guarantees about thread scheduling. Btw, your  
code is not really thread safe since you access a shared resource  
without proper synchronization (although it might work on some Ruby  
platforms).

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![Jean\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@Jean\_G](https://www.ruby-forum.com/u/Jean_G)\
**Post date:** [March 9, 2010, 5:43pm UTC](https://www.ruby-forum.com/t/question-on-threads/184824/3 "2010-03-09T17:43:52Z")

</div>

Jean G. wrote:

> Hello,
> 
> count = 0  
> threads = []
> 
> 10.times do |i|  
> threads[i] = Thread.new do  
> sleep(rand(0.1))  
> Thread.current[“mycount”] = count  
> count += 1  
> end  
> end
> 
> threads.each {|t| t.join; print t[“mycount”], ", " }
> 
> For the code above, why the output numbers are random, rather than  
> from 0 to 9 by increasing?

Because:

(1) each thread sleeps for a random amount of time before capturing and  
incrementing the value of ‘count’; but

(2) you join each thread in the order in which they were started.

Consider, for example, that threads[0] might sleep for 0.09 seconds, but  
threads[1] might sleep for 0.02 seconds. Hence threads[1] will capture a  
lower value than threads[0].

As has already been pointed out, this code is not threadsafe -  
occasionally, two threads may capture the same value of ‘count’. That’s  
because

count += 1

is really a shorthand for

count = count + 1

which is basically:

- read value of count
- add one to this value
- store this value back to count

Thread X could get as far as reading the value of ‘count’ before it is  
suspended; then thread Y could run, read the same value of ‘count’, and  
increment it. Then thread X will be re-scheduled, and also increment and  
save back the same value.

---

<div class="post-metadata">

**Author:** ![Jean\_G](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/ccd318/32.png) [@Jean\_G](https://www.ruby-forum.com/u/Jean_G)\
**Post date:** [March 10, 2010, 9:24am UTC](https://www.ruby-forum.com/t/question-on-threads/184824/4 "2010-03-10T09:24:45Z")

</div>

2010/3/9 Brian C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > ```
> > count += 1
> > 
> > ```
> 
> occasionally, two threads may capture the same value of ‘count’. That’s
> 
> - add one to this value
> - store this value back to count
> 
> Thread X could get as far as reading the value of ‘count’ before it is  
> suspended; then thread Y could run, read the same value of ‘count’, and  
> increment it. Then thread X will be re-scheduled, and also increment and  
> save back the same value.

Brian, thank you for taking the time to do a more elaborate explanation.

One additional thing: since Ruby’s threads can actually return a value  
we can rewrite the original piece to this version, which is also  
thread safe:

lock = Mutex.new  
count = 0

threads = (1…10).map do |i|  
Thread.new do  
sleep(rand(0.1))

```
lock.synchronize do
  count += 1
end

```

end  
end

threads.each do |th|  
puts th.value  
end

Note that #synchronize returns the value returned by the block and by  
that way we return the result of incrementing as the thread’s return  
value which is captured through Thread#value (which also joins the  
thread).

Kind regards

robert

PS: We can make this even shorter, just for the fun of it - I don’t  
really recommend that style:

lock = Mutex.new  
count = 0

(1…10).map do |i|  
Thread.new do  
sleep(rand(0.1))

```
lock.synchronize do
  count += 1
end

```

end  
end.each do |th|  
puts th.value  
end
