有一种对象只要发布了就是线程安全的——不可变对象
不可变对象需要满足的条件
- 对象创建以后其状态就不能修改
- 对象所有域都是final类型 (这样只能对每个域赋值一次,通过构造器初始化所有成员,进行深度拷贝,在get方法中不直接返回对象本身,而是克隆对象并返回克隆)
- 对象是正确创建的(在对象创建期间,this引用没有逸出)
final
关键字: 修饰 类、方法、变量
- 修饰类:被修饰的类不能被继承
(final
类中的成员变量可以根据需要设置为final
,但是final
类中的所有成员方法都会被隐式地指定为final
方法. final修饰类的时候要谨慎原则,除非它以后不会被用来继承,或者出于安全考虑,否则尽量不要将类设置为final类) - 修饰方法:1. 锁定方法不被继承类修改 2. 效率 (一个类的
private
方法会隐式地被指定为final
方法) - 修饰变量: 基本数据类型变量(数值一旦初始化之后就不能修改)、引用类型变量(初始化之后就不能让它指向另外的对象)
package io.haitaoc.concurrency.example.immutable;
import io.haitaoc.concurrency.annotation.NotThreadSafe;
import java.util.HashMap;
import java.util.Map;
@NotThreadSafe
public class ImmutableExample1 {
private final static Integer a=1;
private final static String b="2";
private final static Map<Integer,Integer> map = new HashMap<>();
static{
map.put(1,2);
map.put(3,4);
map.put(5,6);
}
public static void main(String[] args) {
// a=2; // 数值不能改变
// b="3";
// map = new HashMap<>() // 不能指向新的引用
map.put(1,3); // 里面的数值对可以改变
map.entrySet().forEach(entry -> System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue()));
}
private void test(final int a){
// a = 1; // 不允许修改传参为final修饰的变量
}
}
其他方式定义不可变对象
Collections.unmodifiableXXX:List、Map...
package io.haitaoc.concurrency.example.immutable;
import io.haitaoc.concurrency.annotation.NotThreadSafe;
import io.haitaoc.concurrency.annotation.ThreadSafe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ThreadSafe
public class ImmutableExample2 {
private static Map<Integer,Integer> map = new HashMap<>();
static{
map.put(1,2);
map.put(3,4);
map.put(5,6);
map = Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
// a=2; // 数值不能改变
// b="3";
// map = new HashMap<>() // 不能指向新的引用
map.put(1,3); // 里面的数值对可以改变
map.entrySet().forEach(entry -> System.out.println("key:value = " + entry.getKey() + ":" + entry.getValue()));
}
}
Guava第三方包中的,
ImmutableXXX:List、Map...
package io.haitaoc.concurrency.example.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import io.haitaoc.concurrency.annotation.ThreadSafe;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@ThreadSafe
public class ImmutableExample3 {
private final static ImmutableList list = ImmutableList.of(1,2,3);
private final static ImmutableSet set = ImmutableSet.copyOf(list);
// private final static ImmutableMap<Integer,Integer> map = ImmutableMap.of(1,2,3,4);
private final static ImmutableMap<Integer,Integer> map = ImmutableMap.<Integer,Integer>builder().put(1,2).put(3,4).build();
public static void main(String[] args) {
// list.add(4); // 抛出异常
// set.add(4);
map.put(1,4);
}
}