Is double check with final variable working - java

I have class designed for lazy initialization and storing objects which creation is not necessary threadsafe. Here is the code:
class SyncTest {
private static final Object NOT_INITIALIZED = new Object();
private Object object;
/**
* It's guaranteed by outer code that creation of this object is thread safe
* */
public SyncTest() {
object = NOT_INITIALIZED;
}
public Object getObject() {
if (object == NOT_INITIALIZED) {
synchronized (NOT_INITIALIZED) {
if (object == NOT_INITIALIZED) {
final Object tmpRef = createObject();
object = tmpRef;
}
}
}
return object;
}
/**
* Creates some object which initialization is not thread safe
* #return required object or NOT_INITIALIZED
* */
private Object createObject() {
//do some work here
}
}
Here final variable tmpRef is used for storing created object before assigning it to checked variable object . This works in tests but I can't say it's correct for sure and won't be optimsed by compiler.
Can this appraoch be used or object field must be declared as volatile?
Also variant with wrapper class was considered where the line
final Object tmpRef = createObject();
must be replaced with this one:
Object tmpRef = new FinalWrapper(createObject()).getVal();
Wrapper class looks like this:
private class FinalWrapper {
private final Object val;
public FinalWrapper(Object val) {
this.val = val;
}
public Object getVal() {
return val;
}
}
Can some of this examples be safely used in multithreaded environment (especially variant with final local field)?

object = NOT_INITIALIZED;
If you envision this as a trick which will avoid the problems of the usual lazy singleton where you would simply have
object = null;
then it is incorrect; your trick didn't win you any thread safety. You cannot beat the standard double-checked idiom with the volatile variable pointing to the lazily initialized object. So my suggestion would be to get rid of the extra complexity, use null, and use volatile.
Answering your comments:
It's guranteed by JMM that calss initialization with only final fields is always threadsafe.
Class initialization is always thread-safe, regardless of the kind of fields. Every usage of the class is guaranteed to see the objects referred by static fields at least as up-to-date as they were at the time that all class init code completed.
Is the same applicable for local final fields?
The object reached by dereferencing a final field will be at least as up-to-date as it was at the time the constructor of the object containing the final field completed. However, in your solution you never even dereference the field, you just check its value. It is strictly equivalent to check for equality to null as to the value of the NOT_INITIALIZED constant.

You should mark the object variable as volatile to guarantee thread safety, also note that this pattern is only safe in Java 1.5 and later.
This is a tricky piece of code, to quote Joshua Bloch:
The idiom is very fast but also complicated and delicate, so don't be
tempted to modify it in any way. Just copy and paste -- normally not a
good idea, but appropriate here

Related

Immutable Matrix ADT [duplicate]

How to create immutable objects in Java?
Which objects should be called immutable?
If I have class with all static members is it immutable?
Below are the hard requirements of an immutable object.
Make the class final
make all members final, set them
explicitly, in a static block, or in the constructor
Make all members private
No Methods that modify state
Be extremely careful to limit access to mutable members(remember the field may be final but the object can still be mutable. ie private final Date imStillMutable). You should make defensive copies in these cases.
The reasoning behind making the class final is very subtle and often overlooked. If its not final people can freely extend your class, override public or protected behavior, add mutable properties, then supply their subclass as a substitute. By declaring the class final you can ensure this won't happen.
To see the problem in action consider the example below:
public class MyApp{
/**
* #param args
*/
public static void main(String[] args){
System.out.println("Hello World!");
OhNoMutable mutable = new OhNoMutable(1, 2);
ImSoImmutable immutable = mutable;
/*
* Ahhhh Prints out 3 just like I always wanted
* and I can rely on this super immutable class
* never changing. So its thread safe and perfect
*/
System.out.println(immutable.add());
/* Some sneak programmer changes a mutable field on the subclass */
mutable.field3=4;
/*
* Ahhh let me just print my immutable
* reference again because I can trust it
* so much.
*
*/
System.out.println(immutable.add());
/* Why is this buggy piece of crap printing 7 and not 3
It couldn't have changed its IMMUTABLE!!!!
*/
}
}
/* This class adheres to all the principles of
* good immutable classes. All the members are private final
* the add() method doesn't modify any state. This class is
* just a thing of beauty. Its only missing one thing
* I didn't declare the class final. Let the chaos ensue
*/
public class ImSoImmutable{
private final int field1;
private final int field2;
public ImSoImmutable(int field1, int field2){
this.field1 = field1;
this.field2 = field2;
}
public int add(){
return field1+field2;
}
}
/*
This class is the problem. The problem is the
overridden method add(). Because it uses a mutable
member it means that I can't guarantee that all instances
of ImSoImmutable are actually immutable.
*/
public class OhNoMutable extends ImSoImmutable{
public int field3 = 0;
public OhNoMutable(int field1, int field2){
super(field1, field2);
}
public int add(){
return super.add()+field3;
}
}
In practice it is very common to encounter the above problem in Dependency Injection environments. You are not explicitly instantiating things and the super class reference you are given may actually be a subclass.
The take away is that to make hard guarantees about immutability you have to mark the class as final. This is covered in depth in Joshua Bloch's Effective Java and referenced explicitly in the specification for the Java memory model.
Just don't add public mutator (setter) methods to the class.
Classes are not immutable, objects are.
Immutable means: my public visible state cannot change after initialization.
Fields do not have to be declared final, though it can help tremendously to ensure thread safety
If you class has only static members, then objects of this class are immutable, because you cannot change the state of that object ( you probably cannot create it either :) )
To make a class immutable in Java , you can keep note of the following points :
1. Do not provide setter methods to modify values of any of the instance variables of the class.
2. Declare the class as 'final' . This would prevent any other class from extending it and hence from overriding any method from it which could modify instance variable values.
3. Declare the instance variables as private and final.
4. You can also declare the constructor of the class as private and add a factory method to create an instance of the class when required.
These points should help!!
From oracle site, how to create immutable objects in Java.
Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
I. Don't provide methods that modify the mutable objects.
II. Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
An immutable object is an object that will not change its internal state after creation. They are very useful in multithreaded applications because they can be shared between threads without synchronization.
To create an immutable object you need to follow some simple rules:
1. Don't add any setter method
If you are building an immutable object its internal state will never change. Task of a setter method is to change the internal value of a field, so you can't add it.
2. Declare all fields final and private
A private field is not visible from outside the class so no manual changes can't be applied to it.
Declaring a field final will guarantee that if it references a primitive value the value will never change if it references an object the reference can't be changed. This is not enough to ensure that an object with only private final fields is not mutable.
3. If a field is a mutable object create defensive copies of it for
getter methods
We have seen before that defining a field final and private is not enough because it is possible to change its internal state. To solve this problem we need to create a defensive copy of that field and return that field every time it is requested.
4. If a mutable object passed to the constructor must be assigned to a
field create a defensive copy of it
The same problem happens if you hold a reference passed to the constructor because it is possible to change it. So holding a reference to an object passed to the constructor can create mutable objects. To solve this problem it is necessary to create a defensive copy of the parameter if they are mutable objects.
Note that if a field is a reference to an immutable object is not necessary to create defensive copies of it in the constructor and in the getter methods it is enough to define the field as final and private.
5. Don't allow subclasses to override methods
If a subclass override a method it can return the original value of a mutable field instead of a defensive copy of it.
To solve this problem it is possible to do one of the following:
Declare the immutable class as final so it can't be extended
Declare all methods of the immutable class final so they can't be overriden
Create a private constructor and a factory to create instances of the immutable class because a class with private constructors can't be extended
If you follow those simple rules you can freely share your immutable objects between threads because they are thread safe!
Below are few notable points:
Immutable objects do indeed make life simpler in many cases. They are especially applicable for value types, where objects don't have an identity so they can be easily replaced and they can make concurrent programming way safer and cleaner (most of the notoriously hard to find concurrency bugs are ultimately caused by mutable state shared between threads).
However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious. And for objects with a distinct identity, changing an existing objects is much more simple and intuitive than creating a new, modified copy of it.
There are some things you simply can't do with immutable objects, like have bidirectional relationships. Once you set an association value on one object, it's identity changes. So, you set the new value on the other object and it changes as well. The problem is the first object's reference is no longer valid, because a new instance has been created to represent the object with the reference. Continuing this would just result in infinite regressions.
To implement a binary search tree, you have to return a new tree every time: Your new tree will have had to make a copy of each node that has been modified (the un-modified branches are shared). For your insert function this isn't too bad, but for me, things got fairly inefficient quickly when I started to work on delete and re-balance.
Hibernate and JPA essentially dictate that your system uses mutable objects, because the whole premise of them is that they detect and save changes to your data objects.
Depending on the language a compiler can make a bunch of optimizations when dealing with immutable data because it knows the data will never change. All sorts of stuff is skipped over, which gives you tremendous performance benefits.
If you look at other known JVM languages (Scala, Clojure), mutable objects are seen rarely in the code and that's why people start using them in scenarios where single threading is not enough.
There's no right or wrong, it just depends what you prefer. It just depends on your preference, and on what you want to achieve (and being able to easily use both approaches without alienating die-hard fans of one side or another is a holy grail some languages are seeking after).
Don't provide "setter" methods — methods that modify fields or
objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
Don't provide methods that modify the mutable objects.
Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
First of all, you know why you need to create immutable object, and what are the advantages of immutable object.
Advantages of an Immutable object
Concurrency and multithreading
It automatically Thread-safe so synchronization issue....etc
Don't need to copy constructor
Don't need to implementation of clone.
Class cannot be override
Make the field as a private and final
Force callers to construct an object completely in a single step, instead of using a no-Argument constructor
Immutable objects are simply objects whose state means object's data can't change after the
immutable object are constructed.
please see the below code.
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder" +
" for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
Minimize mutability
An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.
JDK immutable classes: String, the boxed primitive classes(wrapper classes), BigInteger and BigDecimal etc.
How to make a class immutable?
Don’t provide any methods that modify the object’s state (known as mutators).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
This prevents clients from obtaining access to mutable objects referred to by fields and modifying these objects directly.
Make defensive copies.
Ensure exclusive access to any mutable components.
public List getList() {
return Collections.unmodifiableList(list); <=== defensive copy of the mutable
field before returning it to caller
}
If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object reference or return the object reference from an accessor.
import java.util.Date;
public final class ImmutableClass {
public ImmutableClass(int id, String name, Date doj) {
this.id = id;
this.name = name;
this.doj = doj;
}
private final int id;
private final String name;
private final Date doj;
public int getId() {
return id;
}
public String getName() {
return name;
}
/**
* Date class is mutable so we need a little care here.
* We should not return the reference of original instance variable.
* Instead a new Date object, with content copied to it, should be returned.
* */
public Date getDoj() {
return new Date(doj.getTime()); // For mutable fields
}
}
import java.util.Date;
public class TestImmutable {
public static void main(String[] args) {
String name = "raj";
int id = 1;
Date doj = new Date();
ImmutableClass class1 = new ImmutableClass(id, name, doj);
ImmutableClass class2 = new ImmutableClass(id, name, doj);
// every time will get a new reference for same object. Modification in reference will not affect the immutability because it is temporary reference.
Date date = class1.getDoj();
date.setTime(date.getTime()+122435);
System.out.println(class1.getDoj()==class2.getDoj());
}
}
For more information, see my blog:
http://javaexplorer03.blogspot.in/2015/07/minimize-mutability.html
an object is called immutable if its state can not be changed once created. One of the most simple way of creating immutable class in Java is by setting all of it’s fields are final.If you need to write immutable class which includes mutable classes like "java.util.Date". In order to preserve immutability in such cases, its advised to return copy of original object,
Immutable Objects are those objects whose state can not be changed once they are created, for example the String class is an immutable class. Immutable objects can not be modified so they are also thread safe in concurrent execution.
Features of immutable classes:
simple to construct
automatically thread safe
good candidate for Map keys and Set as their internal state would not change while processing
don't need implementation of clone as they always represent same state
Keys to write immutable class:
make sure class can not be overridden
make all member variable private & final
do not give their setter methods
object reference should not be leaked during construction phase
The following few steps must be considered, when you want any class as an immutable class.
Class should be marked as final
All fields must be private and final
Replace setters with constructor(for assigning a value to a
variable).
Lets have a glance what we have typed above:
//ImmutableClass
package younus.attari;
public final class ImmutableExample {
private final String name;
private final String address;
public ImmutableExample(String name,String address){
this.name=name;
this.address=address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}
//MainClass from where an ImmutableClass will be called
package younus.attari;
public class MainClass {
public static void main(String[] args) {
ImmutableExample example=new ImmutableExample("Muhammed", "Hyderabad");
System.out.println(example.getName());
}
}
Commonly ignored but important properties on immutable objects
Adding over to the answer provided by #nsfyn55, the following aspects also need to be considered for object immutability, which are of prime importance
Consider the following classes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = mc;
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class MutabilityCheck {
public static void main(String[] args) {
MutableClass mc = new MutableClass();
mc.setName("Foo");
ImmutableClass iMC = new ImmutableClass(mc);
System.out.println(iMC.getMutClass().getName());
mc.setName("Bar");
System.out.println(iMC.getMutClass().getName());
}
}
Following will be the output from MutabilityCheck :
Foo
Bar
It is important to note that,
Constructing mutable objects on an immutable object ( through the constructor ), either by 'copying' or 'cloing' to instance variables of the immutable described by the following changes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = new MutableClass(mc);
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public MutableClass() {
}
//copy constructor
public MutableClass(MutableClass mc) {
this.name = mc.getName();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
still does not ensure complete immutability since the following is still valid from the class MutabilityCheck:
iMC.getMutClass().setName("Blaa");
However, running MutabilityCheck with the changes made in 1. will result in the output being:
Foo
Foo
In order to achieve complete immutability on an object, all its dependent objects must also be immutable
From JDK 14+ which has JEP 359, we can use "records". It is the simplest and hustle free way of creating Immutable class.
A record class is a shallowly immutable, transparent carrier for a fixed set of fields known as the record components that provides a state description for the record. Each component gives rise to a final field that holds the provided value and an accessor method to retrieve the value. The field name and the accessor name match the name of the component.
Let consider the example of creating an immutable rectangle
record Rectangle(double length, double width) {}
No need to declare any constructor, no need to implement equals & hashCode methods. Just any Records need a name and a state description.
var rectangle = new Rectangle(7.1, 8.9);
System.out.print(rectangle.length()); // prints 7.1
If you want to validate the value during object creation, we have to explicitly declare the constructor.
public Rectangle {
if (length <= 0.0) {
throw new IllegalArgumentException();
}
}
The record's body may declare static methods, static fields, static initializers, constructors, instance methods, and nested types.
Instance Methods
record Rectangle(double length, double width) {
public double area() {
return this.length * this.width;
}
}
static fields, methods
Since state should be part of the components we cannot add instance fields to records. But, we can add static fields and methods:
record Rectangle(double length, double width) {
static double aStaticField;
static void aStaticMethod() {
System.out.println("Hello Static");
}
}

Are non-final initializers threadsafe?

It is guranteed or not that every thread sees the value of an instance initializer (the expression right to the equal sign of a field) for a non-final field? For example:
class Foo {
private boolean initialized = false; // Initializer
private final Lock lock = new ReentrantLock();
public void initialize() {
lock.lock()
try {
// Is initialized always false for the first call of initialize()?
if (initialized) {
throw new IllegalStateException("already initialized");
}
// ...
initialized = true;
} finally {
lock.unlock();
}
}
}
In that specific case you are fine because false is also the default value for boolean fields. If your instance variable initialisation were:
private boolean initialized = true;
Then you would have no guarantee that a thread would read true.
Note that if the field were static, you would have such a guarantee due to class loading semantics.
Reference: JLS 17.4.4 (emphasis mine)
The write of the default value (zero, false, or null) to each variable synchronizes-with the first action in every thread.
Although it may seem a little strange to write a default value to a variable before the object containing the variable is allocated, conceptually every object is created at the start of the program with its default initialized values.
The same stands for initialzers that is true for referencing fields:
If you want other threads to see its current value you have to use volatile.
volatile is not surefire however: most of the case you have to use synchronized or other means of synchronizing in order to be sure but in this case a volatile will be enough.
Please refer to this question about the usage of volatile and about thread safety.
Another thing is that only one thread can construct an object and the instance initialization is happening when the object is being constructed. You have to taker care however not to let the this reference escape from the constructor.
It seems to me that what you are looking for is a thread-safe way of lazy initialization. Since direct use of low-level classes such as ReentrantLock can be quite hard to do correctly, I would instead recommend the double-check idiom:
private volatile FieldType field = null; // volatile!
public FieldType getField() {
FieldType result = field; // read volatile field only once, after init
if (result == null) {
synchronized(this) {
result = field;
if (result == null) {
result = computeFieldValue();
field = result;
}
}
}
return result;
}
Note that Double-Check locking requires at least Java 1.5. On older versions of Java it was broken.
A non-final field alone is not guaranteed to be correctly seen, unless you have some other protection such as a lock or synchronized block. i.e. in this case it will always be correct due to the way the value is used.
BTW: For simplicity reasons, I suggest you always structure your code so the component is initialized in the constructor. This avoids such issues as checking the objects is not initialised or initialised twice.

java - volatile keyword also for non-primitives

I am unsure if the volatile keyword should also be used for non-primitives. I have a class member which is set/assigned by one thread, and accessed by another thread. Should I declare this member volatile?
private /* volatile */ Object o;
public void setMember(Object o) {
this.o = o;
}
public Object getMember() {
return o;
}
Here, setMember(...) is called by one thread and getMember() is called by another one.
If it was a boolean, for example, the answer would be yes.
I am using Java 1.4 and the member in this case is read-only. So I am only caring about visibility in this case, hence my question about the volatile keyword.
Yes - volatile has exactly the same significance for reference-type fields that it has for primitive-type fields. Except that in the case of reference types, the members of the object the field refers to must also be designed for multi-threaded access.
You can, and it may be helpful, but remember the keyword just applies to the setting of the reference. It has no effect on multi-thread visibility of the properties inside that object. If it is stateful, you probably want to synchronize around each access to it anyway, to ensure the desired happens-before relationships.
Yes, your code is correct. In this case the reference itself is volatile, so chances to the reference are automatically visible in all other threads, but not changes to the object being referenced.
If we look up AtomicInteger class, it has declared value as volatile , So it can be used in multi-threaded environment without any thread cache issue.
public class AtomicInteger {
private volatile int value;
/**
* Gets the current value.
*
* #return the current value
*/
public final int get() {
return value;
}
/**
* Sets to the given value.
*
* #param newValue the new value
*/
public final void set(int newValue) {
value = newValue;
}
}
But if you think reference to AtomicInteger it shelf will be modified with different AtomicInteger objects by many threads; then you need volatile for that reference too.
private volatile AtomicInteger reference = new AtomicInteger(0);
Mostly it won't be the case; only value of the object will changed; hence declare it as final.
private final AtomicInteger reference = new AtomicInteger(0);

Synchronized blocks in constructors

I have a class with a static var like so
private static Object sMyStaticVar;
if i want to assign a value to this var in the constructor I have code like
if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
where someRuntimeObject is an object that is not available at the time my class is loaded and therefore prevents me from declaring my static var like the below
private static Object sMyStaticVar = new CustomObject(someRuntimeObject);
my question is, is the initialization of the static var object in the constructor thread safe? My instincts tell me its not and i should synchronise using the non-runtime class type as the lock, like the below
synchronized(MyClass.class)
{
if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
}
(as opposed to the runTime type obtained from getClass())
but as my instincts are usually wrong I would be grateful if anyone could shed some light on this for me!
If it is static, you should not assign it in the constructor. Make a static initializer method that does that public static synchronized void initialize(someRuntimeObject).
Note the synchronized keyword: it is is the same as synchronizing on MyClass.class
You are right, the following is open to race conditions:
if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
Two threads could check sMyStaticVar at the same time, see null, create two objects, etc...
This means that you need synchronization. You could either synchronize on some existing object (there are multiple choices), or you could create an object just for the prurpose, so that you don't have to share the lock with anyone else, risking unnecessary contention:
private static Object sMyStaticVar;
private static Object sMyStaticVarLock = new Object();
Then, in the constructor:
synchronized(sMyStaticVarLock)
{
if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
}
This syncrhonization is needed, but it's not enough to achieve thread safety.
You also need to ensure visibility of the field's value when you access it. So, you should either declare that field as volatile or add the same synchronization to every access of that field.

How does "this" escape the constructor in Java?

I've heard about this happening in non thread-safe code due to improperly constructed objects but I really don't have the concept down, even after reading about in in Goetz's book. I'd like to solidify my understanding of this code smell as I maybe doing it and not even realize it. Please provide code in your explanation to make it stick, thanks.
Example : in a constructor, you create an event listener inner class (it has an implicit reference to the current object), and register it to a list of listener.
=> So your object can be used by another thread, even though it did not finish executing its constructor.
public class A {
private boolean isIt;
private String yesItIs;
public A() {
EventListener el = new EventListener() { ....};
StaticListeners.register(el);
isIt = true;
yesItIs = "yesItIs";
}
}
An additional problem that could happen later : the object A could be fully created, made available to all threads, use by another thread ... except that that thread could see the A instance as created, yesItIs with it "yesItIs" value, but not isIt! Believe it or not, this could happen ! What happen is:
=> synchronization is only half about blocking thread, the other half is about inter-thread visibility.
The reason for that Java choice is performance : inter-thread visibility would kill performance if all data would be shared with all threads, so only synchronized data is guaranteed to be shared...
Really simple example:
public class Test
{
private static Test lastCreatedInstance;
public Test()
{
lastCreatedInstance = this;
}
}
This is the reason why double-checked locking doesn't work. The naive code
if(obj == null)
{
synchronized(something)
{
if (obj == null) obj = BuildObject(...);
}
}
// do something with obj
is not safe because the assignment to the local variable can occur before the rest of the construction (constructor or factory method). Thus thread 1 can be in the BuildObject step, when thread 2 enters the same block, detects a non-null obj, and then proceeds to operate on an incomplete object (thread 1 having been scheduled out in mid-call).
public class MyClass{
String name;
public MyClass(String s)
{
if(s==null)
{
throw new IllegalArgumentException();
}
OtherClass.method(this);
name= s;
}
public getName(){ return name; }
}
In the above code, OtherClass.method() is passed an instance of MyClass which is at that point incompletely constructed, i.e. not yet fulfilling the contract that the name property is non-null.
Steve Gilham is correct in his assesment of why double checked locking is broken. If thread A enters that method and obj is null, that thread will begin to create an instance of the object and assign it obj. Thread B can possibly enter while thread A is still instantiating that object (but not completing) and will then view the object as not null but that object's field may not have been initialized. A partially constructed object.
However, the same type of problem can arrise if you allow the keyword this to escape the constructor. Say your constructor creates an instance of an object which forks a thread, and that object accepts your type of object. Now your object may have not be fully initialized, that is some of your fields may be null. A reference to your object by the one you have created in your constructor can now reference you as a non null object but get null field values.
A bit more explanation:
Your constructor can initialize every field in your class, but if you allow 'this' to escape before any of the other objects are created, they can be null (or default primative) when viewed by other threads if 1. They are not declared final or 2. They are not declared volatile
public class Test extends SomeUnknownClass{
public Test(){
this.addListner(new SomeEventListner(){
#Override
void act(){}
});
}
}
After this operation instanse of SomeEventListner will have a link to Test object, as a usual inner class.
More examples can be find here:
http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html
Here's an example of how uninitialized this of OuterClass can be accessed from inside of inner class:
public class OuterClass {
public Integer num;
public OuterClass() {
Runnable runnable = new Runnable() { // might lead to this reference escape
#Override
public void run() {
// example of how uninitialized this of outer class
// can be accessed from inside of inner class
System.out.println(OuterClass.this.num); // will print null
}
};
new Thread(runnable).start();
new Thread().start(); // just some logic to keep JVM busy
new Thread().start(); // just some logic to keep JVM busy
this.num = 8;
System.out.println(this.num); // will print 8
}
public static void main(String[] args) {
new OuterClass();
}
}
Output:
null
8
Pay attention to OuterClass.this.num instruction in the code

Categories

Resources