深入ReentrantLock底层原理01

1、Thread线程

package top.juntech.lock;import java.util.concurrent.locks.ReentrantLock;public class TestLock {public static void main(String[] args) {Thread t1 = new Thread(){public void run(){testSync();}};Thread t2 = new Thread(){public void run(){testSync();}};t1.setName("t1");t2.setName("t2");t1.start();t2.start();}public static void testSync(){System.out.println(Thread.currentThread().getName());try {Thread.sleep(2000);}catch (Exception e){e.printStackTrace();}}}

在这里,我们的线程t1,t2同时调用了testSync方法,尽管有thread.sleep(2000),但我们发现t1,t2几乎是同时打印出来的,为什么呢,在t1进入这个方法里面,虽然在睡眠但不影响主线程继续执行,接下来t2启动,那我们怎么使他们一前一后执行呢,答案时加锁。我们这里就将ReentranLock.

1、添加一个全局变量: ReentranLock reen = new ReentranLock(true);

2、在方法里面添加lock方法

3、释放锁

代码如下:

package top.juntech.lock;import java.util.concurrent.locks.ReentrantLock;   //初始化锁对象public class TestLock {static  ReentrantLock reentrantLock = new ReentrantLock(true);public static void main(String[] args) {Thread t1 = new Thread(){public void run(){testSync();}};Thread t2 = new Thread(){public void run(){testSync();}};t1.setName("t1");t2.setName("t2");t1.start();t2.start();}public static void testSync(){try {reentrantLock.lock();   //加锁System.out.println(Thread.currentThread().getName());try {Thread.sleep(2000);}catch (Exception e){e.printStackTrace();}}finally {reentrantLock.unlock();  //释放锁}}}

这样,我们就可以看到t1打印完了过了2s左右,才开始打印t2.

2、思考

既然java里面有关键字sysnchronized,为什么还需要ReentranLock?

java中的线程是和操作系统中的线程是一一对应的,synchronized在执行多线程时,t1进入synchronized方法后,t2也想进去,它会让t2操作操作系统的一个函数,t2占用之后,会让操作系统的哪个函数产生阻塞,直到t1醒来,执行完释放,t2拿到锁之后,接着执行同步代码块。

2.1 多线程同步内部是如何实现的

wait/notify,synchronized ,ReentranLock

模拟一些同步的思路:

自旋锁:

volatile int status = 0;
void lock(){while(!compareAndSet(0,1)){}//lock
}
void unlock(){status = 0;
}
boolean compareAndSet(int except,int newValue){//compare  and  set操作,修改status成功返回true
}

缺点: 耗费cpu资源,没有竞争到锁的线程会一直占用cas操作。

思路:让得不到锁的线程让出cpu

不能用wait,因为wait是和sync一起使用的,单独使用会报错,且wait不只是拿来使线程阻塞的,它还可以用来线程通信。

yield+自旋锁

volatile int status = 0;
void lock(){while(!compareAndSet(0,1)){yield();//自己实现 }//lock
}
void unlock(){status = 0;
}
boolean compareAndSet(int except,int newValue){//compare  and  set操作,修改status成功返回true
}

要解决自旋锁的性能问题必须让竞争锁失败的的线程不空转,而是在获取不到锁的时候让出cpu,yeild()方法可以让出cpu;但是yield并不能完全解决问题,在线程数为2个时,可以使用,但线程数比较多的时候,就不适用了,因为yeild是由操作系统控制的。

yield方法,请参考:https://blog.csdn.net/zhuwei898321/article/details/72844506

sleep+自旋锁

volatile int status = 0;
void lock(){while(!compareAndSet(0,1)){sleep(10};//自己实现 }//lock --- 1s
}
void unlock(){status = 0;
}
boolean compareAndSet(int except,int newValue){//compare  and  set操作,修改status成功返回true
}

缺点:睡眠时间不确定,易造成cpu资源浪费

park+自旋锁

这里要使用的是UNSAFE类里面的park方法,下面是park方法的具体使用

package top.juntech.lock;import java.util.concurrent.locks.LockSupport;public class TestPark {public static void main(String[] args) {Thread t1 = new Thread(){public void run(){testSync();}};t1.setName("t1");t1.start();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("--------main-------");   // 3、打印mainLockSupport.unpark(/*线程名*/t1);   //4、叫醒t1,继续执行,打印t1---2}public static void testSync(){System.out.println(/*Thread.currentThread().getName()*/ "t1 -----1"); //1.首先打印t1 --1LockSupport.park();   //2.t1开始睡眠System.out.println("t1 ----- 2");}
}

伪代码如下:

volatile int status = 0;
Queue parkQueue; //集合 数组
void lock(){while(!compareAndSet(0,1)){park();}//lock    20sunpark();
}
void unlock(){status = 0;lock_notify();
}
boolean compareAndSet(int except,int newValue){//compare  and  set操作,修改status成功返回true
}
void park(){//将当前线程添加到等待队列parkQueue.add(currentThread)//将当前线程释放cpu,阻塞releaseCpu();
}
void lock_notify(){//得到要唤醒的线程头部线程Thread t = parkQueue.header();//唤醒等待线程unpark(t);
}

更多详情

设置为vip可见的都可访问下面链接地址,即可观看原文
更多详情请访问: juntech

深入ReentrantLock底层原理01相关推荐

  1. 【多线程学习笔记】sychronized关键字底层原理、sychronized与ReentrantLock、volatile和synchronized

    文章目录 sychronized释义 synchronized关键字最主要的三种使用方式: synchronized底层原理: 同步代码块: 同步方法 当前类的class对象作为锁 锁升级 Synch ...

  2. 并发底层原理:线程、资源共享、volatile 关键字

    并发底层原理:线程.资源共享.volatile 关键字 1.线程 1.1 定义任务 1.2 Thread 类 1.3 使用 Executor 1.4 从任务中产生返回值 1.6 优先级 1.7 后台线 ...

  3. java锁的底层原理

    知识整理 Synchronized 内置锁,JVM级别 使用 底层 锁升级过程.CAS操作的缺点[替换线程和copy mw] 优化 代码优化:同步代码块.减少锁粒度.读锁并发 JDK自带 偏置锁.轻量 ...

  4. 嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他...

    来自:烟雨星空 前言 上篇文章介绍了 HashMap 源码后,在博客平台广受好评,让本来己经不打算更新这个系列的我,仿佛被打了一顿鸡血.真的,被读者认可的感觉,就是这么奇妙. 原文:面试官再问你 Ha ...

  5. SQL 中 left join 的底层原理(各种JOIN的复杂度探究)

    01. 前言 写过或者学过 SQL 的人应该都知道 left join,知道 left join 的实现的效果,就是保留左表的全部信息,然后把右表往左表上拼接,如果拼不上就是 null.除了 left ...

  6. 你知道 Sql 中 left join 的底层原理吗?

    总第165篇/张俊红 01.前言 写过或者学过 Sql 的人应该都知道 left join,知道 left join 的实现的效果,就是保留左表的全部信息,然后把右表往左表上拼接,如果拼不上就是 nu ...

  7. java aqs详解_Java AQS底层原理解析

    AQS底层原理 AQS(AbstractQueuedSynchronizer)是一个抽象同步队列,JUC(java.util.concurrent)中很多同步锁都是基于AQS实现的. AQS的基本原理 ...

  8. synchronized的使用和底层原理、锁状态的膨胀升级过程

    文章目录 1. synchronized介绍 2. synchronized底层原理 3. synchronized锁的膨胀升级过程 4. synchronized锁状态的记录位置 5. synchr ...

  9. Java并发编程-synchronized底层原理

    synchronized底层原理与Monitor密切相关 1.Java对象头 以 32 位虚拟机为例 普通对象 对象的类型,如Student类型,Teacher类型等是由KlassWord来表示的,它 ...

  10. synchronized原理_面试必备—Synchronized 关键字使用、底层原理

    在并发编程中存在线程安全问题,主要原因有: 1.存在共享数据 2.多线程共同操作共享数据 关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchro ...

最新文章

  1. 实现一个基于 SharePoint 2013 的 Timecard 应用(下)
  2. bt下载加速 BitTorrent trackers服务器列表
  3. Advanced Transact-SQL for SQL Server 2000 学习译文
  4. html:(24):内联式css和嵌入式css
  5. android 开源项目列表【持续整理中。。。】
  6. windows 7 64bit python3.3安装pyqt
  7. 如何在单例模式下禁止init
  8. 吴恩达机器学习(十)支持向量机(SVM)
  9. matlab做叠加定理仿真,实验一 仿真软件的使用与叠加原理的验证
  10. OPPO R9KM手机刷机救砖线刷包附驱动教程
  11. 世界上最好的惯性动作捕捉设备Xsens,你不应该错过的Xsens MVN Animate Pro
  12. 计算机关闭没用的端口,关闭端口的方法,小编教你如何关闭电脑不用的端口
  13. JAVA代码实现计算器功能
  14. reboot流程简述
  15. dcos 正确的查看日志的姿势
  16. 瑞萨开发记录01:点亮一颗LED灯(R5F104FEA芯片)
  17. 如何在头条做营销:2022今日头条营销价值洞察报告.pdf(附下载链接)
  18. 学习学习学习学习学习学习
  19. 两条命令彻底修复动态链接库
  20. APMServ 使用

热门文章

  1. 全文检索技术Lucene
  2. Rhythmbox中文乱码解决
  3. bootstrap之双日历时间段选择控件—daterangepicker
  4. OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
  5. 【区块链技术工坊32期】陈军:区块链+供应链金融解决方案及落地案例
  6. linux中的apche服务
  7. 一点处的导数无法确定单调性
  8. fastlane:构建、测试和发布 React Native 应用程序
  9. MPP(无主备)环境搭建
  10. APS车间排产软件实现企业生产数据可视化