I was able to solve this one correctly but I can't say I understood what I did too well.
So each thread is modifying the array, adding plus 1 to the current index, which initially starts out as 0 for each element.
Why, then, after 5 threads going over it, is the value equal to 1? Shouldn't each element be 4?
And what's wrong with locking "this" instead of the "values" array?
Can someone explain the logic of this one
Under discussion
Comments (4)
- Popular
- New
- Old
You must be signed in to leave a comment
Dave Andrea
21 September 2020, 12:39
The counter variable is tracking the array index. The incrementCount() adds 1 to the counter, and getCounter() is called as the index of the current value. So the counter has no effect on the values in the array. It's the ++ that actually increments each value from 0 to 1. The main side effect of threads interfering with each other would be that incrementCounter() could be called more than once before the array value is incremented. So you would have gaps in the array that are still equal to 0.
Values is the exact thing that we want to be locked so that's why we lock that. I'm still learning about this at the higher levels so I can't give much of an answer, but ideally you want to lock the smallest block of code that you can so that threads can do as much as they can without having to wait. Locking a whole class when a single array will do the trick would be overkill and decrease performance. +4
Onur Bal
21 September 2020, 12:52
Thanks for the great explanation Dave. It cleared up a lot of things for me.
There is still one question in my mind, though:
Doesn't each thread run this line on each element of the array? So in my mind, the first thread increases each element from 0 to 1. Then the next one comes along, the elements are now equal to 1, and then their values are increased to 2, and so on. In the output, though, it's all 1s. Why is this the case? 0
Dave Andrea
22 September 2020, 19:13
I began experimenting with the code and then started writing a reply, but the more I got into it, the more I realize this is still a bit fuzzy to me. I'd rather not say anything than say something incorrect. I need to reread some stuff. Any time this happens, I go for Bruce Eckel's On Java 8. It usually sorts things out. The reality is that the further you go in Java, the more you try to avoid dealing with threads directly. You still use them of course, but there are new classes that do a lot of the synchronization for you. And this task is a great lesson in why that was a great thing for the Java developers to do!
+1
Onur Bal
22 September 2020, 21:18
It's really tricky indeed, but this is one of the things I love about programming. I have run the code in different variations on my own as well, and I have found that locking (values) is what produces the consistent outcome of all values being 1. If, instead, you lock (this) for example, or don't have a synchronised block at all, then there are some 2 values in there as well. Which made me come to the conclusion that syncrhonising the list makes it so that the
command gets executed only once per value. +1