线程安全策略

策略1 - 不可变对象

  • 对象创建以后其状态就不能修改。
  • 对象所有域都是final类型。
  • 对象是正确创建的(在对象创建期间,this引用没有逸出)。

final关键字:类、方法、变量

  • final类:不能被继承。
  • 修饰方法:锁定方法不被继承类修改。
  • 修饰变量:基本数据类型变量(值不能变更),引用类型变量(不能再指向其它对象)。
@Slf4j
@ThreadSafe
public class ImmutableExample2 {
    private static Map map = Maps.newHashMap();
    static {
        map.put(1, 2);
        map.put(3, 4);
        map.put(5, 6);
        map = Collections.unmodifiableMap(map);
    }
    public static void main(String[] args) {
        map.put(1, 3);
        log.info("{}", map.get(1));
    }
}

Guava提供了许多不可变的集合

@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 map2 = ImmutableMap.builder()
            .put(1, 2).put(3, 4).put(5, 6).build();

    public static void main(String[] args) {
        System.out.println(map2.get(3));
    }
}

策略2 - 线程封闭

仅在单线程内访问数据,不需要同步

2.1 Ad-hoc线程封闭

指维护线程封闭性的职责完全由程序实现来承担。Ad-hoc线程封闭是非常脆弱的,因为没有任何一种语言特性,例如可见性修饰符或局部变量,能将对象封闭到目标线程上。
当决定使用线程封闭技术时,通常是因为要将某个特定的子系统实现为一个单线程子系统。程序控制实现,最糟糕,忽略

2.2 堆栈封闭

在栈封闭中,只能通过局部变量才能访问对象。栈封闭(也被称为线程内部使用或者线程局部使用)比Ad-hoc线程封闭更易于维护,也更加健壮。

2.3 ThreadLocal线程封闭:特别好的方法
策略3 - JUC工具包
  • 以Concurrent前缀的并发类,如ConcurrentHashMap
  • 含有Blocking的阻塞类,如LinkedBlockingDeque
  • 以Atomic为前缀的原子变量类,如AtomicInteger
    -辅助工具类,如CountDownLatch
策略4 - 无状态
  • 没有实例域
  • 如Servlet
策略5 - 同步锁
  • synchronized
  • ReentrantLock
  • ReentrantReadWriteLock

你可能感兴趣的:(线程安全策略)