1.使用基本的final创建:数据类型变量不可被修改,但是引用类型变量仍然可以被修改,线程不安全
package com.zr.concurrency.test.notsafe.immutable;
import com.zr.concurrency.annotation.ThreadNotSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@ThreadNotSafe
public class ImmutableExample1 {
private final static Map<Integer,Integer> map=new HashMap<>();
static {
map.put(1,2);
map.put(3,4);
map.put(4,6);
}
public static void main(String[] args) {
map.put(1,3);
log.info("{}",map.get(1));
}
}
2.使用Collections.unmodifiableMap()让引用类型变量不可变,线程安全
package com.zr.concurrency.test.safe.immutable;
import com.zr.concurrency.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@ThreadSafe
public class ImmutableExample2 {
private static Map<Integer,Integer> map=new HashMap<>();
static {
map.put(1,2);
map.put(3,4);
map.put(4,6);
map= Collections.unmodifiableMap(map);
}
public static void main(String[] args) {
map.put(1,3);
log.info("{}",map.get(1));
}
}
3.使用谷歌的Immutable和final让引用类型变量不可变,线程安全
package com.zr.concurrency.test.safe.immutable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.zr.concurrency.annotation.ThreadSafe;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ThreadSafe
public class ImmutableExample3 {
private final static ImmutableList<Integer> list=ImmutableList.of(1,2,3);
private final static ImmutableSet<Integer> set=ImmutableSet.copyOf(list);
private final static ImmutableMap<Integer,Integer> map=ImmutableMap.of(1,2,3,4);
public static void main(String[] args) {
map.put(1,3);
log.info("{}",map.get(1));
}
}
总结:
只使用final创建的不可变引用类型变量仍然可以被修改,线程不安全。
使用java自带的Collections.unmodifiable…()可以让变量不可变,线程安全。
使用谷歌的Immutable创建的对象为不可变对象,不可被修改,线程安全。