手撸JDK之ReentrantLock锁那点事


前置思想

首先明确一点ReentrantLock与synchronized最大的不同点在于synchronized是锁住了对象的头部,而ReentrantLock是类似于我们买一把锁,锁住我们不想因为多线程下导致资源的原子性 ,可见性的问题,在明确这一点时我们的锁其实与生活中的所没太大区别,生活中的锁无非就是大门挂一把锁,这样我们就告诉别人此处以上锁,唯一不同的是程序锁必须由上锁的人来解锁,而生活中我们可以持有别人的锁进行开锁。
手撸JDK之ReentrantLock锁那点事

主要使用到的类
AtomicInteger:主要保证此锁的原子性与可见性,以及涉及到后面的可重入锁的状态,注:volatile只能保证资源的可见性,并不能保证原子性Thread:当前那个线程持有这把锁【PS:也就是谁持有了锁,此处到后面可重入锁,以及解锁所需要的】LinkedBlockingQueue:没抢到锁对象的容器LockSupport:切换线程状态
交代完了开怼!!!!

/**
* 线程状态定义
*/
AtomicInteger state = new AtomicInteger();

/**
* 那个线程持有锁
*/
Thread ownerThread = null;

/**
* 存放线程的容器
*/
LinkedBlockingQueue<Thread> waiters = new LinkedBlockingQueue<>();

这步没啥可说的继续!!

public boolean tryLock() {
//不用每次都进行CAS操作,如果当期状态为0我直接返回抢锁成功
if (state.get() == 0) {
//CAS抢锁
if (state.compareAndSet(0, 1)) {
//将抢到锁的线程设定为当前锁的持有者
ownerThread = Thread.currentThread();
return true;
}
} else if (ownerThread == Thread.currentThread()) {
System.out.println("重入锁成功!!!!");
state.set(state.get() + 1);
return true;
}
return false;
}

此处主要用到了CAS机制,如果修改成功证明已抢到锁,失败则加入队列,以及重入锁如果是当前线程那么获取锁成功,并且在状态+1【PS:此处状态+1主要是为了可重入锁,应为重入锁的本质需要你加锁几次就要释放几次】

public void lock() {
//真公平锁 如果没有!waiters.isEmpty(),在锁的上一个持有者他也会抢
if (!waiters.isEmpty() || !tryLock()) {
//没抢到锁进入等待队列
waiters.add(Thread.currentThread());
for (; ; ) {
if (tryLock()) {
//移除并且返回队列头部
waiters.poll();
return;
} else {
//没抢到 进入阻塞(WAITING)
LockSupport.park();
}
}
}
}

如果当前没有线程持有锁则直接返回,有则将他加入队列并且阻塞【PS:当然一些猿认为使用LinkedBlockingQueue不就已经是公平锁了么(先入先出),其实不然比如:有三个线程,1抢锁成功,在释放后其实1也参与抢锁了,也就是插队!!此处的插队就导致看似公平的锁变的不公平了】

public void unlock() {
//如果不是当前线程那么不允许释放锁
if (Thread.currentThread() != ownerThread) {
throw new RuntimeException("不是你的别乱动,你不是锁的持有者");
}
//释放锁的过程,每次过来减一
if (state.decrementAndGet() == 0) {
ownerThread = null;
//获取第一个等待的元素并且通知他开始抢锁了,此时还不能移除
//在真正抢到锁后才能移除队列
Thread waiter = waiters.peek();
if (waiter != null) {
LockSupport.unpark(waiter);
}
}
}

此处我们释放锁的时候必须是当前持有锁的线程,如果其他线程来释放锁呢就乱套了
PS:如有不对的地方请大手不吝啬指出

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

手撸JDK之ReentrantLock锁那点事

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 手撸JDK之ReentrantLock锁那点事
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏