• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Object Synchronization

 
Simon Ingram
Ranch Hand
Posts: 173
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A question from Max�s book (i.e. Habibi, Patterson, Camerlengo)
Pg 115/6. Object Synchronization.
Thread 1
1. myVector.add(�Hello�);
2. myArrayList.add(�Hello�);
3. myVector.add(�World�);
4. myArrayList.add(�World�);
5. System.out.println(�myVector: � + myVector);
6. System.out.println(�myArrayList: � + myArrayList);
Thread 2
a. myVector.add(�Cruel�);
b. myArrayList.add(�Cruel�);

according to the book, if Thread 1 �slices out� at line 3 and Thread 2 slices in executing lines a and b, the output for MyVector would be the following:
MyVector: Hello Cruel World
The argument runs that since the add method of MyVector is synchronized and the code above is not, the add method will run atomically and produce the output shown.
I must be missing something here; surely Thread 1 in line 3 will maintain its lock on myVector and will block Thread 2 access to the add method until line 3 completes. Thread 2 will have to wait, not carry on processing Cruel. The sequence should therefore be:
MyVector: Hello World Cruel
I'm missing something, right?
 
Andrew Monkhouse
author and jackaroo
Marshal Commander
Pie
Posts: 12007
215
C++ Firefox Browser IntelliJ IDE Java Mac Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Simon,
The errata for Max's book says that:
Chapter 4, p.116, first paragraph, first sentence
says "at line three". It's more clear to say "Before line 3"

To be honest, I think the errata makes this more confusing: if we get a clean swap before line 3 is executed, then I don't think that there should be a problem predicting the output. It is only if the thread swap happens in the middle of one of the myArrayList.add() calls that you can get indeterminant results. But this is just from my quick reading - I may have missed something as well: I will go back and reread it after work.
Regards, Andrew
 
Simon Ingram
Ranch Hand
Posts: 173
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I agree, Andrew. The errata makes it worse. Also Max defines what the JVM does i.e. Thread 1: lines 1,2,3 then Thread 2: lines a and b. Given this sequence, I don't see how the Array List output is indeterminate. An ArrayList produces inderterminate output because it's methods are not synchronized so that since the JVM can slices in and out in an unpredictable way, so the output cannot be predicted. But Max tells us what the JVM is doing, so the output from the Array List can only be Hello Cruel World. Am I right or does still stalk my path?
Simon
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Simon,
I think you're right. Given the scenario described, both lists will have the same content.
Best,
Phil.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah - I know that this may shock some people here, but I say Max is right in this case. If anything he understates the range of possible results for myArrayList - I would add possibilities like
"MyArrayList: Hello Cruel"
"MyArrayList: Hello World"
NullPointerException
ArrayIndexOutOfBoundsException
It doesn't matter if we've been told that "Cruel" was added before "World" - if there's no synchronization, then communication between threads is highly unreliable. Each thread has its own working memory which it uses to keep track of data read from the heap - meaning that threads perform their operations on cached copies of heap data rather than accessing the heap each and every time the data is mentioned in code. Eventually changes made to working memory will be propagated back to the "real" data on the heap (main memory) - but without synchronization, there's no guarantee when this will happen. When "World" is added, thread 1 may still be looking at a copy of the data which has just "Hello" rather than "Hello Cruel". So thread 1 has "Hello World" and thread 2 has "Hello Cruel", and depending on what order the final updates of main memory occur in, either of these may appear as the final result.
As for the two exceptions I listed - stuff like that may be possible because the single ArrayList object is really a collection of different bits of data which must be read from / written to main memory, and without synchronization it's possible that the internal fields of the ArrayList are seen in an inconsistent state. E.g. the JDK 1.4.2 ArrayList has two instance fields: and int size, and an Object[] elementData. What happens if thread 1 adds an element, but thread 2 sees the increase in size before it sees the new data in elementData? Thread 2 may try to access that last element, currently null. Leading to NullPointerException. Or maybe the elementData array doesn't even have space for that next element, and it was about to resize to accommodate the latest add(). Leading to ArrayIndexOutOfBoundsException. There are probalby a lot of different ways things could go wrong here, depending on implementation details. Or maybe one or both of these exceptions are never actually possible for a particular JVM. But my point is that if we're accessing shared mutable data from different threads without synchronization, all sorts of weird things may occur which are quite different from what we might expect.
[Andrew]: To be honest, I think the errata makes this more confusing:
It's reality which is confusing here - the errata merely brings this into focus better. The point is that it doesn't matter if events "really" occurred in a particular sequence - due to their cached data, threads may end up behaving as though they happened in a different sequence.
I would say that it would be better if the errata had said "just before line 3" rather than "before line 3". But that's a minor point, and it doesn't seem that anyone here is interpreting it otherwise.
[ December 14, 2003: Message edited by: Jim Yingst ]
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,
Ah - I know that this may shock some people here, but I say Max is right in this case.

?!
Max'book is great ! As all good books, it may include a few mistakes, but it has very few, AFAIK. I didn't read the errata, but the only mistake I can remember is a useless notifyAll() line in a lock method, along with its comment. Apart that very little issue, Max's book really deserves a very high score, so it's hard to understand what you meant above.
Back to the subject. You just wrote a very interesting post, thank you ! We often think of the possible issues related to unsynchronized multithreading access in terms of undetermined behaviour when *multiple* related variables are accessed by the multiple threads. But of course, as you explained above, an ArrayList groups multiple instance variables within itself, hence the possible issues. What misleaded me in Max's example, is that it described a precise sequence of execution, giving a fake feeling of predictability. Your comments above should be added to the book ! Thanks for having pointed that out.
Best,
Phil.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Max's book really deserves a very high score, so it's hard to understand what you meant above.
Agreed. I was just acknowledging that Max and I have been known to disagree once or twice. For four or five pages at a time. Seemed a bit unusual that I was the one agreeing with him this time. But even though Max and I sometimes disagree, I would still agree with the vast majority of things Max has said or written, and his book is the best SCJD resource out there. Does that clarify what I meant?
 
Philippe Maquet
Bartender
Posts: 1872
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jim,
Agreed. I was just acknowledging that Max and I have been known to disagree once or twice. For four or five pages at a time.

OK, I remember a few of them, your intellectual duels are even a good memory ! But there had nothing to do with what Max wrote in his book, as far as I remember.
As you wrote your post just after mine, and as I remembered a quite long discussion of mine about that useless notifyAll(), I felt your post like directed at me.
Argh ! It's so hard to read under the lines sometimes !
Best,
Phil.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But there had nothing to do with what Max wrote in his book, as far as I remember.
Well, the notifyAll() was from the book, and was one of the points where we disagreed. Until Max clarified what he meant later. And I disagree with some of Max's book statements about FileChannel atomicity and thread safety. Long discussion there which we needn't repeat. But that doesn't invalidate the >99% of the book that's great stuff.
[ December 15, 2003: Message edited by: Jim Yingst ]
 
Simon Ingram
Ranch Hand
Posts: 173
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jim, thanks very much for note. It clarified the point perfectly. I think Philippe is right, if Max had added these details it would have eliminated any confusion and it's just the kind of technical insight that examinees need. I'm not said anything bad about Max's book, just that I was confused on this particular point. Thanks guys, it's all clear now.
 
Vishwa Kumba
Ranch Hand
Posts: 1066
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
When I read pages 115/6 in Max's book, I sure thought there was something missing there.....Yes, missing it was..Jim's explanation!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic