Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Collections synchronization  RSS feed

 
Darryl Failla
Ranch Hand
Posts: 129
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In order to make a LinkedList thread-safe, I used Collections.synchronizedList(new LinkedList()). Does this make my List thread-safe without any explicit synchronizing on the List at all? I have read murmurings about having to explicitly synchronize on the object if an iterator is being used.

I have one method using an iterator and others that do not (but do remove or add elements). They are all very short methods. In order to protect my application, I initiate:

synchronized(list){

at the start of each method. Is there any real adverse effect of this, am I overkilling myself, or am I doing what is necessary?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Darryl]: Does this make my List thread-safe without any explicit synchronizing on the List at all? I have read murmurings about having to explicitly synchronize on the object if an iterator is being used.

Yes - one place to find uch "murmurings" is in the API of Collections.synchronizedList() and similar methods. This states quite explicitly that you need to synchronized if iterating. Unfortunately it fails to warn you that you probably need to synchronize in many other cases as well. In general, any time you need to call more than one method on the synchronized list, ask yourself: what would happen if another thread added or removed entries to the list in between the synchronized method calls? Usually, unpredicatble errors would occur, and the way to prevent this is by externally synchronizing on the list, just as you describe.

[Darryl]: Is there any real adverse effect of this, am I overkilling myself, or am I doing what is necessary?

Well, it's possible you may be synchronizing more than necessary, and any time you sync more than necessary you may cause the code to execute more slowly than it would with less synchronization. However in general, I would say that by default, you should use a sync block which is big enough to cover all accesses to the list within a given method. If there's only one access, not in a loop, then you could skip the sync block and just rely on the internal sync of the synchronizedList(). (Though I would recommend you just ditch that method entirely, and always provide explicit sync instead.)

It's possible that in some cases, you may be able to determine through careful analysis that you need less synchronization than I have just described. Maybe you can split it into several smaller sync blocks, or omit the sync blocks entirely and just rely on the internal sync of a synchronizedList(). (If you must.) But be very careful with this, as there's often some subtle way this can go wrong. If you're not absolutely sure it's OK to use less synchronization (and if you're not willing to tolerate occasional random errors in your app), then don't.

So, sounds like you're doing exactly the right thing. Aside from the fact that using Collections.synchronizedList() is pretty much pointless, yes? But that's usually the case.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!