1. 什么是线程安全问题
线程安全问题就是多个线程同时对于某个共享资源的访问,导致的原子性,可见性和有序性的问题,而这些问题会导致共享数据存在一个不可预测性,使得程序在执行过程中会出现一些超过预期的一个结果
2. 解决线程安全问题的方式
一般情况下解决线程安全问题的方式是增加同步锁,常见的是像synchronzied,lock等等,由于导致线程安全问题的根本原因是多线程并行访问。对共享资源加锁之后呢,多个线程在访问这个资源的时候,必须要先获得锁,也就是先获得访问资格,而同步锁的特征是在同一个时刻只允许一个线程访问这样一个资源,直到锁被释放,虽然这种方式,可以解决线程安全性的一个问题,但同时带来的是加锁和释放锁所带来的一个性能开销,因为加锁涉及用户空间和内核空间的一个转换以及上下文切换
3. 如何在不加锁解决线程安全问题
如何在性能和安全性之间去取得一个平衡,这就引出了一个无锁并发的概念,一般来说会有以下几种说法
- 通过自选锁(CAS),所谓自选锁是指线程在没有抢占的锁的情况下先自旋指定的次数,去尝试获得锁
- 乐观锁,给每个数据增加一个版本号,一旦数据发生变化,则去修改这个版本号,那在Java里面,有一个CAS的一个机制,去完成乐观锁的一个功能
- 在程序设计中,尽量去减少共享对象的一个使用,从业务上去实现隔离避免并发