线程安全策略(一)-不可变对象

有一种对象只要发布了就是线程安全的——不可变对象

不可变对象需要满足的条件

  • 对象创建以后其状态就不能修改
  • 对象所有域都是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 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 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 map = ImmutableMap.of(1,2,3,4);

    private final static ImmutableMap map = ImmutableMap.builder().put(1,2).put(3,4).build();

    public static void main(String[] args) {
        // list.add(4);                // 抛出异常
        // set.add(4);
        map.put(1,4);

    }
}

你可能感兴趣的:(线程安全策略(一)-不可变对象)