From: Robert Klemme on

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
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
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
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
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/