竞太条件和临界区:(其实就是多线程访问相同资源的描述术语) 多个线程访问了相同的资源,向这些资源执行了写操作,并对执行顺序有要求。就可能出现竞态条件。 临界区:一段代码,如果在多线程执行的情况下,会对结果产生影响。那么这段代码就是临界区。 竞态条件:是指多线程环境下竞争共享资源的情形。 原子性操作: 原子操作是一个步骤,或者多个步骤,但是执行顺序不能被打乱,也不能被切割而执行其中一部分。(不可中断)这样整个操作视为是原子的。 将临界区转换成为原子性操作。保证线程安全。 CAS机制: 这是一个底层实现原子性的机制。 Compare and swap 比较和交换,属于硬件原语,处理器提供的基本的内存操作的原子性 CAS操作需要两个参数(旧值,新值):比较旧值然后更新新值。 在操作的时候先比较旧值是否发生变化,如果已经发生了变化:说明别的线程已经对其修改了,不写入新值。 如果没有发生变化:说明这个值没有变化,可以写入新值。 J.U.C包提供了原子操作封装类:(其实是使用CAS机制实现的) AtomicBoolean:原子更新Boolean类型 AtomicInteger:原子更新整型 AtomicLong:原子更新长整型 还有更新数组的、更新字段的、更新引用的。 jdk1.8更新了:提供了效率更高的计数器。多线程时效率较高,适合频繁的更新但不频繁读取的场景。 计数器:DoubleAdder、LongAdder 更新器:DoubleAccumulator、LongAccumulator。(增强版的计数器,除了列加之外,还可以执行自定义的计算) 例如,实现整数的自增: AtomicInteger i = new AtomicInteger(0); public void add(){ // 底层使用Unsafe.class类实现。该类可以直接操作内存。实现CAS机制,从而保证了原子性。Unsafe可能出现平台兼容,不安全。 i.incrementAndGet(); } CAS的缺点: 1:循环+CAS是的线程处于高频运转,资源浪费 2:只针对单个变量,多个数据无法同时控制原子性。