美文网首页
java多线程中显式锁的轮询检测策略

java多线程中显式锁的轮询检测策略

作者: 4553675200ad | 来源:发表于2019-05-08 14:21 被阅读0次

显式锁简介

java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile,java5.0增加了一种新的机制:ReentrantLock。

锁像synchronized同步块一样,是一种线程同步机制,与synchronized不同的是ReentrantLock提供了一种无条件的、可轮询的、定时的以及可以中断的锁获取操作,并且所有的加锁和解锁的方法都是显式的,所以也叫显式锁。

synchronized的实现中包含了锁机制,但是锁的获取和释放不能人为的进行控制,所以当我们要定时获取锁,检测锁是否被占用时就应当使用显式锁。

显式锁涉及的类和接口

ReentrantLock实现了Lock接口,位于Java的J.U.C包中,包含了一下几个主要方法:

  1. void lock(),获取锁;

  2. void unlock(),释放锁;

  3. boolean trylock(),仅在调用时锁为空闲状态才获取该锁;

  4. boolean tryLock(long time, TimeUnit unit),如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

显式锁的简单使用

下面我们就分别使用synchronized和lock实现小红借书的需求。

需求:小明和小红去借书,每人借10本。一个人借完之后才允许另外一个人借。

分析:

  1. 小明和小红相当于 2个线程;
  2. 借10本书视为一个操作即循环10次;
  3. 一个人借完之后才允许另外一个人借。

要实现必须保证借书的10次操作中间不能发生线程的切换,因此可以使用 synchronized 同步块或显示锁 ReentrantLock 来保证。

synchronized方式

ReentrantLock方式

本案例中在lock 和unlock 中间的代码块与synchronized 包裹的代码块是等效的。可以保证在执行unlock之前该线程不会让出资源给其它线程执行。

实现轮询锁

需求:小明和小红去借书,但是书只有一本,假如小明借到了,看完这本书需要5秒,

在小明读书的时间内,小红还会多次去借书,直到小明归还小红才能借到。

分析:

  1. 小明和小红去借书,但是书只有一本 ,从这里可以分析出需要两个线程;
  2. 假如小明借到了,看完这本书需要5秒,借到书可以视为获取到锁;
  3. 在小明读书的时间内,小红还会多次去借书,可以视为小红未获得锁,所以需要多次尝试去获得锁;
  4. 直到小明归还小红才能借到,可以视为小明的线程释放锁,小红获得锁。

总结

不论使用synchronized 还是使用显示锁lock都可以解决代码块同步的问题。synchronized 使用更方便,获得锁和释放锁不需要手动处理,但控制粒度不够细致。lock显式锁需要使用lock()手动加锁,unlock()手动释放锁,使用起来相对复杂,但可以实现更精细的锁控制。

使用trylock结合轮询可以实现检测锁是否空闲的效果。

相关文章

网友评论

      本文标题:java多线程中显式锁的轮询检测策略

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