From: Robert Klemme on 2 Jul 2010 10:40 Hi, the recent thread "Serious concurrency problems on fast systems" inspired me to put together a small demo that shows how different ways of concurrency control affect execution. The example shares a dummy configuration with a single long value. Multiple threads access the shared resource read only and depending on test scenario a single thread updates it from time to time. Concurrency control is done in these ways: 1. Plain synchronized on a single shared resource. 2. Synchronized but with redundant storage and update via observer pattern. 3. Copy on write with an immutable object and an AtomicReference. You can download it here http://docs.google.com/leaf?id=0B7Q7WZzdIMlIMDI4ZDk0ZGItYzk1My00ZTc1LWJlYmQtNDYzNWNlNzA3YTJm&hl=en Have fun robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Lew on 2 Jul 2010 13:32 Robert Klemme wrote: > the recent thread "Serious concurrency problems on fast systems" > inspired me to put together a small demo that shows how different ways > of concurrency control affect execution. The example shares a dummy > configuration with a single long value. Multiple threads access the > shared resource read only and depending on test scenario a single thread > updates it from time to time. Concurrency control is done in these ways: > > 1. Plain synchronized on a single shared resource. > > 2. Synchronized but with redundant storage and update via observer pattern. > > 3. Copy on write with an immutable object and an AtomicReference. > What about 'volatile'? or <http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/ AtomicLong.html> ? > You can download it here > > http://docs.google.com/leaf?id=0B7Q7WZzdIMlIMDI4ZDk0ZGItYzk1My00ZTc1L.... > Thank you for your contribution. Aside from the semantics that you illustrate for updatable values, nothing beats immutable (read-only, value fixed at initialization) objects for safe and fast concurrency. "But that's only for when you can get away with read-only values!" I hear someone saying. Yes, and one must always consider when one can get away with read-only values. I've been on several projects where programmers used mutable objects for concurrently-accessed objects with read-only usage. Often they used lazy initialization, with broken double-checked locking yet! for objects that never change value once initialized. Had they considered the advantages of immutability, even constancy (e.g., for read-only Strings), they would have prevented the concurrency and performance issues their misguided implementations caused. -- Lew
From: Robert Klemme on 3 Jul 2010 05:22 On 02.07.2010 19:32, Lew wrote: > Robert Klemme wrote: >> the recent thread "Serious concurrency problems on fast systems" >> inspired me to put together a small demo that shows how different ways >> of concurrency control affect execution. The example shares a dummy >> configuration with a single long value. Multiple threads access the >> shared resource read only and depending on test scenario a single thread >> updates it from time to time. Concurrency control is done in these ways: >> >> 1. Plain synchronized on a single shared resource. >> >> 2. Synchronized but with redundant storage and update via observer pattern. >> >> 3. Copy on write with an immutable object and an AtomicReference. >> > > What about 'volatile'? > > or > <http://java.sun.com/javase/6/docs/api/java/util/concurrent/atomic/ > AtomicLong.html> > ? That would have been an alternative for the special scenario here (just a single long). But I wanted to mimic a configuration which typically consists of multiple values while at the same time save the effort of providing more properties. From a pedagogical point of view it probably would have been better to have at least one additional property. >> You can download it here >> >> http://docs.google.com/leaf?id=0B7Q7WZzdIMlIMDI4ZDk0ZGItYzk1My00ZTc1L... >> > > Thank you for your contribution. You're welcome! > Aside from the semantics that you illustrate for updatable values, > nothing beats immutable (read-only, value fixed at initialization) > objects for safe and fast concurrency. > > "But that's only for when you can get away with read-only values!" I > hear someone saying. > > Yes, and one must always consider when one can get away with read-only > values. I completely agree: if you can get away with immutability that's the best option you can have. Often though, changing the configuration at runtime (even if rarely) is desirable for some kinds of applications in order to avoid the shutdown restart loop. > I've been on several projects where programmers used mutable > objects for concurrently-accessed objects with read-only usage. Often > they used lazy initialization, with broken double-checked locking yet! *shudder* > for objects that never change value once initialized. Had they > considered the advantages of immutability, even constancy (e.g., for > read-only Strings), they would have prevented the concurrency and > performance issues their misguided implementations caused. Absolutely. A typical scenario where lazy initialization looks good at first sight but is rather weak in hindsight is the typical singleton pattern where the static reference is initialized in the accessor. While you sometimes may get away with leaving this unsynchronized and thus potentially initializing multiple times often you need to synchronize. Voilá, there is the bottleneck - even on systems with few cores (as my example showed). Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Christian on 4 Jul 2010 05:28 Am 02.07.2010 16:40, schrieb Robert Klemme: > > Hi, > > the recent thread "Serious concurrency problems on fast systems" > inspired me to put together a small demo that shows how different ways > of concurrency control affect execution. The example shares a dummy > configuration with a single long value. Multiple threads access the > shared resource read only and depending on test scenario a single thread > updates it from time to time. Concurrency control is done in these ways: > > 1. Plain synchronized on a single shared resource. > > 2. Synchronized but with redundant storage and update via observer pattern. > > 3. Copy on write with an immutable object and an AtomicReference. > > You can download it here > > http://docs.google.com/leaf?id=0B7Q7WZzdIMlIMDI4ZDk0ZGItYzk1My00ZTc1LWJlYmQtNDYzNWNlNzA3YTJm&hl=en > > > Have fun > > robert > You could also try the by Java provided (Reentrant)ReadWriteLock ... it might (I am not sure there) be cheaper with lots of reads and few writes than normal synchronization.
From: Robert Klemme on 4 Jul 2010 08:31 On 04.07.2010 11:28, Christian wrote: > Am 02.07.2010 16:40, schrieb Robert Klemme: >> >> the recent thread "Serious concurrency problems on fast systems" >> inspired me to put together a small demo that shows how different ways >> of concurrency control affect execution. The example shares a dummy >> configuration with a single long value. Multiple threads access the >> shared resource read only and depending on test scenario a single thread >> updates it from time to time. Concurrency control is done in these ways: >> >> 1. Plain synchronized on a single shared resource. >> >> 2. Synchronized but with redundant storage and update via observer pattern. >> >> 3. Copy on write with an immutable object and an AtomicReference. >> >> You can download it here >> >> http://docs.google.com/leaf?id=0B7Q7WZzdIMlIMDI4ZDk0ZGItYzk1My00ZTc1LWJlYmQtNDYzNWNlNzA3YTJm&hl=en > > You could also try the by Java provided (Reentrant)ReadWriteLock ... > it might (I am not sure there) be cheaper with lots of reads and few > writes than normal synchronization. That's an excellent idea: https://docs.google.com/leaf?id=0B7Q7WZzdIMlIZjAxZDg5YzYtNzE3YS00ZjAyLTgzMmQtMTExMmYwZjcwODAz&sort=name&layout=list&num=50 However, while it is faster than plain old synchronized on the global resource, this confirms that centralized locking is an inferior approach in highly concurrent systems. :-) Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
|
Next
|
Last
Pages: 1 2 Prev: java.sql.Timestamp: Bug or... Next: Possible BUG in Mixed Code Security Warning? |