Java并发编——Java锁的实现原理

作者: 糖宝_ | 来源:发表于2018-06-09 06:31 被阅读23次

一、基础概念

多CPU:一台计算机上多个物理CPU

多核:一个CPU上多个核心

超线程技术:一个核心多个执行执行单元

二、CPU内存架构:

高度缓存L1、L2、L3:

4核8线程:

我刚整理了一套2018最新的0基础入门和进阶教程,无私分享,加Java学习裙 :678-241-563 即可获取,内附:开发工具和安装包,以及系统学习路线图

这样就存在缓存一致性问题。

解决缓存一致性问题的方法:总线锁和缓存锁

(1)总线锁

这样之后i的值都为2,但是我们期待的结果是i = 3。

那么总线锁的意思是当CPU1拿到变量处理完的时候CPU2处于阻塞状态,当CPU1处理完之后,CPU2才能进行处理。

总线锁带来的问题:存在阻塞问题,性能较低。

(2)缓存锁

缓存锁只锁定缓存的数据, 不锁定总线。

CPU1修改完i的值,写回到内存中。此时CPU2嗅探到总线上i的值与本地缓存中i的值不一致,则缓存中i的值失效,CPU2从总线锁上去取i的值,并进行运算。

缓存一致性:处理器上提供的缓存协议,保证了缓存一致性。

缓存协议MESI:

M:modify

E:execusive

S:shared

I :invalid

E:execusive状态:数据在本地缓存中,切与内存中数据一致;其他的CPU缓存中没有:

S:shared状态:每个核心的缓存都一样,且与内存一致:

M和I状态:其中一个核心修改了值,那么其他的核心的缓存失效

三、Volatile和Synchronized

Volatile:保证共享变量的可见性

向处理器发送一条LOCK#使

1、引起处理器缓存回写到内存中

2、使其他的处理器缓存失效

Synchronized:可见性和排他性

可以修饰方法和代码块,支持重入

jdk6之前,是重量级锁

//实例锁:public class App { public synchronized void demo(String param){ synchronized (this){ //实例锁 } } public static void main(String[] args){ App app = new App(); //下面两个代码排队执行 new Thread(()->{ app.demo(Thread.currentThread().getId()+""); }).start(); new Thread(()->{ app.demo(Thread.currentThread().getId()+""); }).start(); }}123456789101112131415161718

创建两个实例就不行了:

//实例锁:public class App { public synchronized void demo(String param){ synchronized (this){ //实例锁 } } public static void main(String[] args){ App app = new App(); App app1 = new App(); //下面两个代码排队执行 new Thread(()->{ app.demo(Thread.currentThread().getId()+""); }).start(); new Thread(()->{ app1.demo(Thread.currentThread().getId()+""); }).start(); }}12345678910111213141516171819

全局锁:对所有实例都可以

//全局锁:public class App { public synchronized void demo(String param){ synchronized (App.class){ //全局锁 } } public static void main(String[] args){ App app = new App(); //下面两个代码排队执行 new Thread(()->{ app.demo(Thread.currentThread().getId()+""); }).start(); new Thread(()->{ app.demo(Thread.currentThread().getId()+""); }).start(); }}123456789101112131415161718

锁的转换:

无锁状态->偏向锁->轻量级锁->重量级锁

偏向锁:大部分情况下,多线程之间不仅仅不会存在锁竞争,而且还总是由同一个线程获得

如果多次访问的是同一个线程的话,只需要获取一次锁

相关文章

  • java并发

    1.并发编程中的锁 并发编程中的各种锁java高并发锁的3种实现Java并发机制及锁的实现原理 2.线程池核心线程...

  • Java并发编——Java锁的实现原理

    一、基础概念 多CPU:一台计算机上多个物理CPU 多核:一个CPU上多个核心 超线程技术:一个核心多个执行执行单...

  • Java并发机制的底层实现原理 一

    Java并发机制的底层实现原理中我们今天看下几个简单的并发锁:目的:为了减少加锁和释放锁带来的开销,Java SE...

  • 由浅深入理解java多线程,java并发,synchronize

    由浅深入理解java多线程,java并发,synchronized实现原理及线程锁机制 [TOC] 多进程是指操作...

  • 5、ReentrantLock

    ReentrantLock 是 java并发包下互斥锁,功能和synchronized差不多。但是他们的实现原理有...

  • 并发整理(二)— Java线程与锁

    现已全部整理完,其他两篇并发整理(一)—Java并发底层原理并发整理(三)— 并发集合类与线程池 本篇主要讲锁实现...

  • 技术点

    1Java集合主要是hashmap实现原理2.多线程问AQS源码、并发工具类源码、锁的实现原理、阻塞队列源码、线程...

  • 理解synchronize

    Java并发编程 Synchronized及其实现原理

  • 死磕系列

    内存模型 【死磕Java并发】-----深入分析synchronized的实现原理 【Java并发编程实战】—–s...

  • 并发整理(三)— 并发集合类与线程池

    并发整理最后一篇,之前两篇并发整理(一)— Java并发底层原理并发整理(二)— Java线程与锁 这篇讲的主要是...

网友评论

    本文标题:Java并发编——Java锁的实现原理

    本文链接:https://www.haomeiwen.com/subject/uaczsftx.html