线程同步

线程同步

1 非阻塞同步机制

乐观锁
可用并发执行,使用失败重试机制处理冲突(CAS)。

1.1 CAS

CPU硬件所支持的指令,含义是:
我认为V变量的值是A,如果是,那么将V的值更新为B如果不是不修改并告诉我V的值实际是多少。

1.1.1 使用模式

首先从V中读取值A,并根据A计算新值B然后通过CAS以原子方式将V中的值由A设置为B。如果失败根据需求,选择回放该动作。

1.1.2 实际应用
1.1.2.1 原子变量

可用作为一种更好的volatile变量使用。
原子变量提供了与volatile变量相同的内存语义,还支持原子更新操作。

  1. AtomicInteger
  2. AtomicLong
  3. AtomicBoolean
  4. AtomicReferance
  5. 更新器类
  6. 数组类
  7. 复合变量类
1.1.2.2 非阻塞算法

这些算法使用底层的原子机器指令代替锁来确保数据在并发访问中的一致性。

算法关键
非阻塞算法的关键在于,找出如何将原子修改的范围缩减到一个变量上,同时还要维护数据一致性。

实现类

  1. 非阻塞链表
  2. 非阻塞栈
1.1.3 缺点

由调用者处理处理竞争问题(重试、回退、放弃)
锁将自动处理竞争问题(线程在获取锁之前一直阻塞)

1.2 volatile

volatile是一种比较轻量级的同步机制,在使用这些变量时不会发生上下文切换或线程调度问题。

1.2.1 缺点

不能用于原子的复合操作。

2 阻塞同步机制

基于锁的同步机制

2.1 内置锁(synchronized)

2.2 显示锁

ReetrantLock并不是替代内置加锁的办法,而是在内置加锁不试用的时,作为一种可选择的高级功能。

2.2.1 Lock

Lock提供了一种无条件、可轮询、可定时、可中断的所获取操作。
Lock提供了和synchronized相同的互斥性和内存可见性。
获取锁时有着和进入同步代码块相同的内存语义,在释放锁时,同样有着与退出同步代码块相同的内存语义。

2.2.1.1 特点

优点

提供更多的高级选项。

  1. 可中断
  2. 可定时
  3. 可尝试
  4. 公平性

缺点

更加危险
由程序员保证锁的释放(在finally中手工释放锁)

2.2.1.2 高级功能

轮询锁

lock.tryLock

定时锁

tryLock中可以设置超时时间

可中断锁

tryLock、lockInterruptibly,在获取锁的时候保持对中断的响应。

公平性

公平性将由于在挂起线程和恢复线程时存在开销而极大降低性能。
一般情况下,非公平锁性能优于公平锁。

非公平锁

当线程请求一个非公平锁,如果发出请求的同时该锁的状态变成可用,那么这个线程将跳过队列中所有的等待线程并获取这个锁。

公平锁

在公平锁中,如果有另外一个线程持有这个锁或者由其他线程在队列中等待这个锁,那么新发出请求的线程将被放入队列中。

2.2.2 ReadWriteLock

一个资源可用被多个读操作或一个写操作访问。
一个ReadWriteLock中暴露两个Lock对象(ReadWriteLock的不同视图),一个用于读、一个用于写。

2.2.3 Lock&synchronized

仅当内置锁无法满足需求时,才考虑使用Lock

2.2.4 锁的问题

在挂起和恢复线程中存在很大的开销,并且通常存在较长时间的中断。

3 非阻塞VS阻塞

  1. 一般情况下,原子变量的性能超过锁的性能(因锁导致的线程上下文切换开销大于原子变量重试开销)
  2. 在高度竞争的情况下,锁的性能超过原子变量(原子变量重试开销大于因所导致的线程上下文切换开销)
wenxinzizhu wechat
扫一扫,添加我的微信,一起交流共同成长(备注为技术学习)