There are various methods in Collections such as synchronizedList, synchronizedMap, etc. These are for wrapping non threadsafe collections in a way that synchronizes important operations. Don't use them. Ever. In a similar theme, never write code that looks like the following:synchronized(myMap){ doStuffTo(myMap); }Concurrency is not an afterthought. If you're going to be doing concurrent programming you should be using datastructures designed for concurrent use. java.util.concurrent has a number of good ones. Further, you should avoid explicitly synchronizing if at all possible and have your structures be internally threadsafe. If you try to ensure thread safety by synchronizing on the structures you're mutating you will a) Make a mistake. Almost certainly. This will introduce bizarre bugs which you will have a serious headache tracking down. b) Have worse concurrent performance than using a properly designed datastructure - e.g. a ConcurrentHashMap has finer grained locking, so it actually is possible for multiple threads to write to it in a safe manner. c) Have really ugly code with synchronization logic spread all over the place. This is not a minor point - if your threading code is simple, it's much easier to determine if it's correct (although still not easy).As most of us would probably have to admit that at some point we've written synchronized blocks like the code above... it's good advice to read, put bluntly like that.
-
Java collections and concurrency (14 messages)
- Posted by: Joseph Ottinger
- Posted on: January 14 2008 13:41 EST
In "Java collections and concurrency," David MacIver offers some advice that should be fairly obvious to anyone who really thinks about it from the standpoint of "why are there so many fixes to this if there's no problem?"Threaded Messages (14)
- Re: Java collections and concurrency by Jeff Segal on January 14 2008 14:10 EST
- Re: Java collections and concurrency by Robert Varga on January 14 2008 17:28 EST
- "thread safe" and "business model" by Tom Eugelink on January 15 2008 03:22 EST
- Re: "thread safe" and "business model" by peter veentjer on January 15 2008 03:54 EST
- Re: "thread safe" and "business model" by Robert Varga on January 15 2008 05:22 EST
-
Re: "thread safe" and "business model" by Wille Faler on January 15 2008 09:14 EST
- omg by Leif Ashley on January 15 2008 09:34 EST
- "thread safe" and "business model" by Tom Eugelink on January 15 2008 03:22 EST
- It depends by peter veentjer on January 15 2008 03:23 EST
- Re: Java collections and concurrency by Karl Banke on January 15 2008 05:44 EST
- Re: Java collections and concurrency by James Watson on January 15 2008 12:59 EST
- In the land of the blind, the one eyed man is king by Leif Ashley on January 15 2008 09:31 EST
- Re: In the land of the blind, the one eyed man is king by James Watson on January 15 2008 12:48 EST
- True too by Leif Ashley on January 15 2008 01:23 EST
- Re: In the land of the blind, the one eyed man is king by James Watson on January 15 2008 12:48 EST
- synchronization does suck by Bill Burke on January 15 2008 12:05 EST
-
Re: Java collections and concurrency[ Go to top ]
- Posted by: Jeff Segal
- Posted on: January 14 2008 14:10 EST
- in response to Joseph Ottinger
As someone who has experienced a), b) and c) I agree wholeheartedly. -
Re: Java collections and concurrency[ Go to top ]
- Posted by: Robert Varga
- Posted on: January 14 2008 17:28 EST
- in response to Joseph Ottinger
Also, instead of having the object state separated to multiple attributes each having only a few possible values, it might be possible to represent the combined value-space with a single int value, which can be set atomically, practically implementing a finite-state-machine with an AtomicInteger or a volatile int accessed/mutated via an AtomicIntegerFieldUpdater holding the state (or an AtomicLong or volatile long accessed/mutated via an AtomicLongFieldUpdater). It can do wonders instead of a locked block or synchronized block for mutating related attributes. Of course it does not apply in all cases. -
"thread safe" and "business model"[ Go to top ]
- Posted by: Tom Eugelink
- Posted on: January 15 2008 03:22 EST
- in response to Robert Varga
Has anyone ever tried to build a thead safe business model? -
Re: "thread safe" and "business model"[ Go to top ]
- Posted by: peter veentjer
- Posted on: January 15 2008 03:54 EST
- in response to Tom Eugelink
In most cases the business model is stored in the database and I let the database worry about synchronization by setting the correct isolation level or add some explicit locking (pessimistic/optimistic). When all business objects are isolated within a single thread (so a single transaction) you don't need to worry about synchronization on business objects in Java anymore. -
Re: "thread safe" and "business model"[ Go to top ]
- Posted by: Robert Varga
- Posted on: January 15 2008 05:22 EST
- in response to Tom Eugelink
Yes. It is actually quite easy to do with some thinking done in advance. The Java Concurrency in Practice book is quite a good read to kickstart that thinking. -
Re: "thread safe" and "business model"[ Go to top ]
- Posted by: Wille Faler
- Posted on: January 15 2008 09:14 EST
- in response to Tom Eugelink
Has anyone ever tried to build a thead safe business model?
You mean one were different managers avoid/are not allowed to concurrently give engineers different, conflicting directives based on spur-of-the-moment half baked whims? That would be a "no". -
omg[ Go to top ]
- Posted by: Leif Ashley
- Posted on: January 15 2008 09:34 EST
- in response to Wille Faler
LOL - not something I should have read on a conference call (spured by my manager no less). :)Has anyone ever tried to build a thead safe business model?
You mean one were different managers avoid/are not allowed to concurrently give engineers different, conflicting directives based on spur-of-the-moment half baked whims?
That would be a "no". -
It depends[ Go to top ]
- Posted by: peter veentjer
- Posted on: January 15 2008 03:23 EST
- in response to Joseph Ottinger
a) Make a mistake. Almost certainly. This will introduce bizarre bugs which you will have a serious headache tracking down. It depends on the situation. If a structure documents that it exposes the internal used lock as an external lock, using synchronized in this manner is a workable solution. If the enclosing structure is owner of the myMap, it is also a workable solution (personally I would add an extra lock instead of using the monitor lock of the mymap). It isn't something I use on a day to day bases btw. b) Have worse concurrent performance than using a properly designed datastructure - e.g. a ConcurrentHashMap has finer grained locking, so it actually is possible for multiple threads to write to it in a safe manner. It depends on the situation (again). If need to do some conditional put for example and you don't want to deal with optimistic locking failures, executing some kind of read and write within a mutex is a workable solution. c) Have really ugly code with synchronization logic spread all over the place. This is not a minor point - if your threading code is simple, it's much easier to determine if it's correct (although still not easy). It depends on the situation (yes.. again). In most cases it is better to use higher abstractions and don't fiddle with locks. But in some cases it is mandatory. -
Re: Java collections and concurrency[ Go to top ]
- Posted by: Karl Banke
- Posted on: January 15 2008 05:44 EST
- in response to Joseph Ottinger
There are various methods in Collections such as synchronizedList, synchronizedMap, etc. These are for wrapping non threadsafe collections in a way that synchronizes important operations.
An interesting point. Why would that be true? As long as my concurrent structures are not hit continously but only cautiously the only problem seems to be the performance (b) issue. Yes, it is an issue, but it might not be a massive one. For the other two, using "special" implementations are as succeptible to (a) and (c) as using the wrapped collections.
Don't use them. Ever. -
Re: Java collections and concurrency[ Go to top ]
- Posted by: James Watson
- Posted on: January 15 2008 12:59 EST
- in response to Karl Banke
In terms of performance, we need to make sure we are talking about the right things. The article uses the phrase "concurrent performance" which is in regards to lock contention. It's not related to the overhead of synchronization. I've never tested this, but I bet you'd find that for single-threaded access and low-contention access, the synchronized map access is faster than access for the respective concurrent collection. The essential thing to know about the synchronized collection classes and wrappers is that it's impossible for these classes to synchronize their iterators. Ever place in code where these Collections and Maps are iterated over needs to be synchronized explicitly. This is where the error come in, especially when you are handing them off to other libraries. On a side note, one way to address this is to invert the iterator pattern and hand a method reference (implemented as a simple interface) to a foreach type method.There are various methods in Collections such as synchronizedList, synchronizedMap, etc. These are for wrapping non threadsafe collections in a way that synchronizes important operations.
Don't use them. Ever.
An interesting point. Why would that be true? As long as my concurrent structures are not hit continously but only cautiously the only problem seems to be the performance (b) issue. Yes, it is an issue, but it might not be a massive one. For the other two, using "special" implementations are as succeptible to (a) and (c) as using the wrapped collections. -
In the land of the blind, the one eyed man is king[ Go to top ]
- Posted by: Leif Ashley
- Posted on: January 15 2008 09:31 EST
- in response to Joseph Ottinger
Further, you should avoid explicitly synchronizing if at all possible and have your structures be internally threadsafe.
Yea ok, I don't agree with this one at all. The entire point of synchronize is to keep your code block threadsafe. If I could do that without using synchronize, I would, which you can't, which is why you have it. lola) Make a mistake. Almost certainly. This will introduce bizarre bugs which you will have a serious headache tracking down.
Yea, but if you don't use it, things aren't any easier. Multi-threading bugs are always going to be a bear.b) Have worse concurrent performance than using a properly designed datastructure - e.g. a ConcurrentHashMap has finer grained locking, so it actually is possible for multiple threads to write to it in a safe manner.
Martin Fowler makes strong points for not designing for performance up front. There's no way for anyone, you or me, to predict what the performance will be in the class. Also, if it slows the entire app down by .01%, why would you care?c) Have really ugly code with synchronization logic spread all over the place. This is not a minor point - if your threading code is simple, it's much easier to determine if it's correct
I don't think that's a symptom of the sync block. You can have ugly, almost unreadable code even with the simplest functions. I've seen it. Synchronization just doesn't have anything to do with readable code. Your coding policies should handle that. Multi-threading is probably the most difficult aspect of java development, and I agree we haven't found our utopia. But I can say from my experiences that test driven design goes a long way towards easing the woes of synchronization. I need to start writing my own articles at some point so people pick them apart as well. :) -
Re: In the land of the blind, the one eyed man is king[ Go to top ]
- Posted by: James Watson
- Posted on: January 15 2008 12:48 EST
- in response to Leif Ashley
Martin Fowler makes strong points for not designing for performance up front. There's no way for anyone, you or me, to predict what the performance will be in the class. Also, if it slows the entire app down by .01%, why would you care?
The problem with standard Java synchronization is not performance (it's very fast) but contention. It can become a bottleneck. I think standard synchronization is fine as long as you don't have a lot of threads checking the same monitor often but there are cases where this kind of bottleneck can cause contention issues at a very high level. My personal approach is to first attempt to avoid sharing objects between threads. When I get to the unavoidable minimum amount of communication, only then do I start considering the best approach for managing concurrency. Too often I think Java developers just synchronize mindlessly if they do it at all. -
True too[ Go to top ]
- Posted by: Leif Ashley
- Posted on: January 15 2008 13:23 EST
- in response to James Watson
Too often I think Java developers just synchronize mindlessly if they do it at all.
Yea that's a good point too. I was moving more towards that point... and it's not just about synchronizing too. Good code is good, bad code is *BAD*. lol Still though these are things you just have to know when developing multi-threaded applications, and careful use of sync is one of them. It's not a good idea to blame the tool, synchronize, in this case though and say across the board you want to build thread safe code without sync unless you absolutely need it. Many times that approach leads to chasing red herrings, and clients have to pay the bill for that effort. Just a thought... -
synchronization does suck[ Go to top ]
- Posted by: Bill Burke
- Posted on: January 15 2008 12:05 EST
- in response to Joseph Ottinger
I agree that even the smallest synchronize block causes performance issues. For example, I think they may have fixed this in Java 6+, but serialization used to have a simple synchronized map to hold class metadata that's used in serialization. This bottleneck showed up in benchmarks I did a few years ago at around 100-200 threads. Replacing the syncrhonized map with a concurrent hash map did wonders... Leif wrote:But I can say from my experiences that test driven design goes a long way towards easing the woes of synchronization.
TDD, in my experience does nothing towards easing synchronization woes as these problems only show up in benchmarking, if you're lucky, or worse, in production. -- Bill Burke JBoss, a division of Red Hat http://bill.burkecentral.com