Thread safe immutable classFrom WikiJavabuy this book
There are several very complex techniques to make a class thread safe, the simplest and safest way is to make the the class immutable.
Immutable classA class is said to be immutable if it's fields can't be modified once the object is created. This is normally achieved by declaring the fields A class may be partially immutable and have only some of the fields to be not modifiable. These fields must be initialized in the constructors, as they can't be changed after the creation of the object. Immutable classes are very useful in multithread programs since they are inherently thread safe and they have no issues with synchronization. This is because once they are created they can't be changed from anyone, so you don't need to worry about it. You can just read their values any time and be sure there won't be any issue. It is always recommended, when feasible to make your classes immutable. Using mutable classes as immutable fieldsAs said sometimes having an immutable class is not so simple. For example when a I propose a solution for this: When you are creating the object, (since it is immutable this must be the moment when you set all the fields) you don't save the mutable objects passed to the constructor, but rather you create a copy of each one of them and keep the copy. Similarly in the getter for these fields you don't return the object straight away, but a copy of it. Implementing your class like this there's no way (unless using reflection) to modify the field that you want to be immutable. I'll make this more clear in the example: private final Date birthday; public ImmutablePerson(String name, String surname, Date birthday) { super(); this.birthday = new Date(birthday.getTime()); this.name = name; this.surname = surname; } public Date getBirthday() { return new Date(this.birthday.getTime()); } The Date class is not immutable (I believe it should be though) to use it in an immutable class we need to make impossible to change the values of its fields. We do so as explained above. in the constructor we save a copy of the object passed and in the getter we return a copy of the object. Immutable personhere's the complete immutable person class. note that the Birthday field uses the copy trick for granting immutabilit, while the other fields are Strings. /** * */ package org.wikijava.basic; import java.util.Date; /** * this example shows how to make an ImmutablePerson class * * @author Giulio */ public class ImmutablePerson { public static void main(String[] args) { ImmutablePerson frank = new ImmutablePerson("frank", "lupin", new Date( 75, 11, 23)); System.out.println(frank.toString()); // try to change the birthday of frank frank.getBirthday().setYear(2010); //nothing changed. System.out.println(frank.toString()); } private final String name; private final String surname; private final Date birthday; public ImmutablePerson(String name, String surname, Date birthday) { super(); this.birthday = new Date(birthday.getTime()); this.name = name; this.surname = surname; } public Date getBirthday() { return new Date(birthday.getTime()); } public String getName() { return name; } public String getSurname() { return surname; } public String toString() { StringBuffer result = new StringBuffer(name); result.append(" ").append(surname).append(" ").append( birthday.toString()); return result.toString(); } } this program gives output: frank lupin Tue Dec 23 00:00:00 CET 1975 frank lupin Tue Dec 23 00:00:00 CET 1975 As you see the date hasn't changed after the modification. |
