线程安全策略

策略1 - 不可变对象

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

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

  • final类:不能被继承。
  • 修饰方法:锁定方法不被继承类修改。
  • 修饰变量:基本数据类型变量(值不能变更),引用类型变量(不能再指向其它对象)。
@Slf4j
@ThreadSafe
public class ImmutableExample2 {
    private static Map<Integer, Integer> 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<Integer> 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> map2 = ImmutableMap.<Integer, Integer>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
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容