Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #25848 > unrolled thread

Re: boolean and thread safety

Started byDaniele Futtorovic <da.futt.news@laposte.net.invalid>
First post2011-02-11 20:24 +0100
Last post2011-02-11 22:25 -0500
Articles 2 — 2 participants

Back to article view | Back to comp.lang.java.programmer

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: boolean and thread safety Daniele Futtorovic <da.futt.news@laposte.net.invalid> - 2011-02-11 20:24 +0100
    Re: boolean and thread safety Owen Jacobson <angrybaldguy@gmail.com> - 2011-02-11 22:25 -0500

#25848 — Re: boolean and thread safety

FromDaniele Futtorovic <da.futt.news@laposte.net.invalid>
Date2011-02-11 20:24 +0100
SubjectRe: boolean and thread safety
Message-ID<ij42df$m4v$1@news.eternal-september.org>
On 11/02/2011 19:09, raphfrk@gmail.com allegedly wrote:
> Are booleans inherently thread safe?
>
> I am thinking of something like
>
> public class AsyncBoolean {
>
>      boolean value = false;
>
>      public AsyncBoolean(boolean initValue) {
>          value = initValue;
>      }
>
>      public boolean getValue() {
>          return value;
>      }
>
>      public void setValue(boolean value) {
>          value = newValue;
>      }
>
> }
>
> Assuming I define the variable using
>
> final AsyncBoolean varName = new AsyncBoolean(true);
>
> does this in effect auto-sync, since you can't partially read a byte
> and even if you could it is a boolean anyway?
>
> Since it is declared as final, the reference can't change, so I could
> then call varName.setValue(someValue) and varName.getValue() from
> threads without the need for syncing.

You're mixing different things here. *Assigning* a boolean value, as in
value = true
is atomic, and hence thread-safe.

But what thread safety is about is only marginally atomicity (because
all assignments save those of double and long variables are atomic). The
main point is what a thread "sees". That is, whether it "sees" the
changes operated by another thread.

With respects to that, no primitive type, no matter how small, is
thread-safe. You'll have to ensure synchronisation of information across
threads. The easiest way to do that, assuming the propagation of the
reference to the "AsyncBoolean" instance is ensured, would be to declare
the "value" field /volatile/. Another way would be to synchronise in the
getter and setter.

Have a look at java.util.concurrent.atomic.AtomicBoolean.

-- 
DF.

[toc] | [next] | [standalone]


#25878

FromOwen Jacobson <angrybaldguy@gmail.com>
Date2011-02-11 22:25 -0500
Message-ID<2011021122255478329-angrybaldguy@gmailcom>
In reply to#25848
On 2011-02-11 14:24:36 -0500, Daniele Futtorovic said:

> On 11/02/2011 19:09, raphfrk@gmail.com allegedly wrote:
>> Are booleans inherently thread safe?
>> 
>> I am thinking of something like
>> 
>> public class AsyncBoolean {
>> 
>> boolean value = false;
>> 
>> public AsyncBoolean(boolean initValue) {
>> value = initValue;
>> }
>> 
>> public boolean getValue() {
>> return value;
>> }
>> 
>> public void setValue(boolean value) {
>> value = newValue;
>> }
>> 
>> }
>> 
>> Assuming I define the variable using
>> 
>> final AsyncBoolean varName = new AsyncBoolean(true);
>> 
>> does this in effect auto-sync, since you can't partially read a byte
>> and even if you could it is a boolean anyway?
>> 
>> Since it is declared as final, the reference can't change, so I could
>> then call varName.setValue(someValue) and varName.getValue() from
>> threads without the need for syncing.
> 
> You're mixing different things here. *Assigning* a boolean value, as in
> value = true
> is atomic, and hence thread-safe.
> 
> But what thread safety is about is only marginally atomicity (because
> all assignments save those of double and long variables are atomic). The
> main point is what a thread "sees". That is, whether it "sees" the
> changes operated by another thread.

Not only that, but also in *what order* other threads see changes. 
Given shared non-volatile boolean fields 'startedWork' and 
'finishedWork' both initially false and no memory barriers (volatile, 
synchronization, or otherwise), if Thread #1 executes

	foo.startedWork = true;
	/* ... some work ... */
	foo.finishedWork = true;

then Thread #2 may legitimately print "Can't happen!" from

	if (foo.finishedWork && !foo.startedWork) {
		System.out.println("Can't happen!");
    }

even though Thread #1 ensures that foo.finishedWork only becomes true 
after foo.startedWork is true. While this is relatively easy to 
diagnose when both writes (and reads) affect closely-related shared 
fields, the same surprising behaviour can arise from unrelated objects 
and writes (reads) separated by large stretches of code.

Adding memory barriers or using AtomicFoo types not only ensures that 
changes will be seen but also ensures that the changes will be seen in 
a predictable order.

The Java memory model (defined at the end of the JLS) lays out the 
specific guarantees for various scenarios.

> With respects to that, no primitive type, no matter how small, is
> thread-safe. You'll have to ensure synchronisation of information across
> threads. The easiest way to do that, assuming the propagation of the
> reference to the "AsyncBoolean" instance is ensured, would be to declare
> the "value" field /volatile/. Another way would be to synchronise in the
> getter and setter.
> 
> Have a look at java.util.concurrent.atomic.AtomicBoolean.

All good advice. I'll throw another vote on "read Java Concurrency in 
Practice", too.

-o

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web