Re: Usefulness of "final" (Was: Re: Inserting In a List)
On 04.04.2013 02:29, markspace wrote:
On 4/3/2013 5:10 PM, Arne Vajh=F8j wrote:
It can be very important in multithreaded context.
But it is not what makes a class immutable.
OK, that's true. The section I linked to refers to such objects as
"thread safe immutable." It's both concepts in one package. Objects
that aren't thread safe aren't immutable, and objects that aren't
immutable aren't thread safe. I guess that's why the two go together.
I think there's too much mixed here. "Thread safety" and
"(im)mutability" are two different concepts. They are orthogonal -
albeit related because the latter can help to achieve the former.
Mutability itself is complex as I have tried to show elsewhere in this
thread. Then again thread safety is a much more complex concept.
First of all, objects which are mutable can be thread safe - it depends
on their implementation. (J=F6rg pointed that out already).
Then: you wrote "Objects that aren't thread safe aren't immutable". Now =
this depends on what we mean by "thread safe". An immutable object's
state is guaranteed to be seen by all threads identical (given proper
coding, which might include the use of "final" fields and creation of an =
instance before other threads are started OR handing it over to them in
a thread safe manner w.g. with a blocking queue which memory barriers
through its synchronization).
But: that does not necessarily constitute thread safety. An immutable
object can still be implemented in a thread unsafe manner. For example:
public final class KeyValuePairPrinter {
private final PrintStream out;
public KeyValuePairPrinter(PrintStream out) {
this.out = out;
}
/**
* Print a single line with key "=" value.
* @param key key to print before equals sign
* @param value value to print after equals sign
*/
public void print(Object key, Object value) {
out.print(key);
out.print("=");
out.println(value);
}
}
Now, this class is immutable - but is it thread safe? I'd say no,
because there is no guarantee that key, "=" and value are printed on th=
e
same line in a multithreaded environment.
final is required, but you also have to actually prevent any
modification to the object's state after it is constructed. It is a tw=
o
part process, that is true.
"final" is neither required nor sufficient for immutability AND thread
safety. For example, as long as you ensure there is a memory barrier
between construction and use of an instance final fields are not needed
to ensure other threads see the proper state. Thread safety usually
cannot be ensured by a single class. The typical example is
Collection.synchronizedMap(): if you use the typical pattern "test if a
key is present and if not add it to the Map" without explicit
synchronization the code is not thread safe even though the Map ensures
it's never modified at the same time by two threads and all threads see
all updates from other threads. There are many more examples like that.
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/