线程安全问题

104 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

线程安全问题

非线程安全主要是指多个线程对同一个对象的实例变量进行操作时,会出现值被更改,值不同步的情况. 线程安全问题表现为三个方面: 原子性,可见性和有序性

原子性

原子(Atomic)就是不可分割的意思. 原子操作的不可分割有两层含义: 即使是多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

访问(读,写)某个共享变量的操作从其他线程来看,该操作要么已经执行完毕,要么尚未发生, 即其他线程年看不到当前操作的中间结果

访问同一组共享变量的原子操作是不能够交错的

如现实生活中从 ATM 机取款, 对于用户来说,要么操作成功,用户拿到钱, 余额减少了,增加了一条交易记录; 要么没拿到钱,相当于取款操作没有发生 Java 有两种方式实现原子性: 一种是使用锁; 另一种利用处理器的 CAS(Compare and Swap)指令. 锁具有排它性,保证共享变量在某一时刻只能被一个线程访问. CAS 指令直接在硬件(处理器和内存)层次上实现,看作是硬件锁

可见性

在多线程环境中, 一个线程对某个共享变量进行更新之后 , 后续其他的线程可能无法立即读到这个更新的结果, 这就是线程安全问 题的另外一种形式: 可见性(visibility). 多线程程序因为可见性问题可能会导致其他线程读取到了旧数据 (脏数据).## 2.3 有序性

有序性

有序性(Ordering)是指一个处理器上运行的一个线程所执行的内存访问操作在另外一个处理器运行的其他线程看来是乱序的(Out of Order). 乱序是指内存访问操作的顺序看起来发生了变化