java常用锁机制原理

1. volatile关键字

线程内存模型如下:

java常用锁机制原理_第1张图片

由于每个java线程的正常变量在不加锁的情况下, 会在其工作内存中保存备份,从而导致内存数据不一致的情况, volatile能够保证一个基础变量改变和读取不会换成,直接读主内存的功能。

因此此关键字会使用 在某一类线程读写, 另外所有线程只读的单个变量 的场景中

 

 

2. synchronized 关键字

该关键字常用使用方式:

· (1). 对于普通同步方法,锁是当前实例对象。

 

· (2). 对于静态同步方法,锁是当前类的Class对象。

 

· (3). 对于同步方法块,锁是Synchonized括号里配置的对象。

 

锁的标记使用在对象头中, 对象头的内存结构为:

其中Mark Word字段用来支持锁数据, 具体就不细入。

 

synchronized 关键字可能是下面3种锁之一

(1). 偏向锁

(2). 轻量锁

(3). 重量锁

锁升级过程 偏向锁-->轻量锁-->重量锁(升级后不可逆)

 

偏向锁互斥过程:

java常用锁机制原理_第2张图片

 

特点:

(1). 获得偏向锁的第一个线程只比非同步方法多几纳秒, 速度极快

(2). 如果存在其他线程竞争, 消耗极大,只有等下一次stop the world的时候才会让先前一个线程释放锁。因此如果只有一个线程使用, 偏向锁作用极大。

 

 

轻量锁, 重量锁互斥过程:

java常用锁机制原理_第3张图片

 

注解:

(1). 轻量锁,是对CAS中原子变量的一个限时调用获取锁的过程, 其作用就为自旋锁。如果超过时间,则会自动升级为重量锁, 也就是互斥锁。

(2). 轻量锁使用在一些等待时间特别短并且相对比较稳定的地方, 如: 生产者和消费者中的队列, 插入和获得都比较短,而且较稳定。 和其他单独资源(锁资源程序(不锁逻辑流程))的场景。

(3). 重量锁就是底层的互斥锁, 特点是不过度消耗CPU, 但响应时间缓慢。

 

 

3. 原子操作的实现原理

与原子操作相关的变量有AtomicBoolean(用原子方式更新的boolean值)、AtomicInteger (用原子方式更新的int值)和AtomicLong(用原子方式更 新的long值)

 

常用的操作为compare and swap, 此为传入先前的值和更新的值,如果更新的时候和传入的先前的值不一致,则更新失败。

 

此缺点:

(1). 会有ABA问题, 也就是变量中间被修改了, 但是最后又改回来了,这个时候还会更新成功, 不过一般需求不会有这么苛刻。这个问题可以使用AtomicStampedReference来解决, 此可以支持任何变量(原理为增加版本号信息)。

(2). compare and swap 操作过于耗时, 为自旋操作。

(3). 只能保证一个共享基础变量,如boolean, Interger... 这个可以使用AtomicReference传入对象来使用。

 

 

 

 

 

你可能感兴趣的:(并发编程,java)