Lock接口历史

java1.5版本之前只有synchronized一种锁,lock是java1.5版本之后提供的接口。lock接口与synchronized接口功能相同,但是需要手动获取锁和释放锁。既然提供了lock锁那必然就有一定的优点,例如:

lock锁具有锁的可操作性,可以中断获取和超时获取锁等多种同步获取锁的优点。除此之外,lock锁还有一个非常强大的实现类重入锁和读写锁。

Lock接口的使用

Lock lock  = new ReentrantLock();
lock.lock();
try{
//可能会出现线程安全的操作
}finally{
//一定在finally中释放锁
//也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
lock.ublock();
}

lock接口和synchronized关键字的接口的区别

lock可以尝试非阻塞的获取锁,如果这一时刻没有被其他线程获取到,则成功获取。

Lock接口能被中断的获取锁,获取到锁的线程能够相应中断,当获取到锁的线程被中断时,中断异常将被抛出,并释放锁。

Lock接口可以在指定时间内获取锁,如果在有效时间内未获取到锁则返回。

Lock接口中长用的方法

void lock()  //获取锁

void unlock()  //释放锁

boolean trylock()  //尝试获取锁,如果获取失败返回false

boolean trylcok(long time,TimeUtil util)  //在指定时间内获取锁,若获取失败则返回false

void lockInterruptibly()  //如果当前线程未被中断则获取锁。该方法也是获取锁,与lock()不同的是,该方法在获取过程中可以被中断

Lock中的重入锁ReetrantLock实现类

顾名思义,重入锁就是在一条线程获取到锁之后再次获取锁,就是所谓的重入锁。讲道理synchronized也同样可以做到,不同的是该实现类有个很重到的特性,就是可以实现公平与非公平获取。

公平获取就是线程等待时间越长的越先获取到锁,反之就是非公平获取。事实上,非公平获取要比公平获取的效率要高。

当然该锁是排他锁,也就是说在一个线程获取锁后,其他线程进入等待列队。即同一时刻有且只能有一个线程执行。

Lock锁中的读写锁ReetrantReadWriteLock

与重入锁有所不同的是,读写锁在同一时刻可以有多个线程同时访问。但在写线程访问时,其他读锁和写锁都将被阻塞,进入等待列队。读写锁维护了一对儿锁,一个读锁和一个写锁。通过读写锁分离,使得程序执行效率比一般的排他锁更高。(并发性:在资料上看到的是并发性更高,在这里我觉得效率更容易理解一丢丢)

读锁:readlock();

写锁:writelock();

public class Cache{
static Map<String,Object> map = new HashMap<String,Object>();
static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
static Lock rLock = rwl.readLock();
static Lock wLock = rwl.writeLock();
//获取一个key对应的value
public static final Object get(String key){
r.lock();
try{
return map.get(key);
}finally{
r.unlock();
}
}
//设置key对应的value并返回旧的value
public static fianl Object put(String key,Object value){
w.lock();
try{
return map.put(key,value);
}final{
w.unlock();
}
}
//清空缓存
public static fianl void clear(){
w.lock();
try{
map.clear();
} finally{
w.unlock();
}
}
}

读写锁的锁降级

锁降级是指写锁降级成为读锁。如果当前线程持有写锁,然后将其释放再获取读锁的过程不能称为锁降级。锁降级指的在持有写锁的时候再获取读锁,获取到读锁后释放之前写锁的过程称为锁释放。

锁降级在某些情况下是非常必要的,主要是为了保证数据的可见性。如果当前线程不获取读锁而直接释放写锁,假设此时另外一个线程获取了写锁并修改了数据。那么当前线程无法感知该线程的数据更新。

(没怎么看明白,用程序走几次就明白了。实践见真理)。

最新文章

  1. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】
  2. 011-Scala中的apply实战详解
  3. php学习前的准备
  4. unity3d插件Daikon Forge GUI 中文教程3-基础控件Button和Sprite的使用
  5. Readonly与const初识
  6. 推荐一个很好的富文本web编辑器UEditor
  7. apache2.4配置虚拟主机
  8. xAML中一些控件的用法学习
  9. 给input元素添加float. 去除IE6 下input的空隙
  10. Windows 10环境安装VIM代码补全插件YouCompleteMe
  11. APUE 2 - 进程组(process group) 会话(session) job
  12. 单例模式详解及java常用类
  13. 炫酷:一句代码实现标题栏、导航栏滑动隐藏。ByeBurger库的使用和实现
  14. Scrum冲刺阶段5
  15. 最新sublime text 3 注册码license分享(亲测有效)
  16. linux系统中的文件权限详解(转)
  17. JEECG 开源平台全视频和文档
  18. mint-ui是什么?怎么使用?说出至少三个组件使用方法?
  19. Application-identifier entitlement does not match问题的解决
  20. python学习课件

热门文章

  1. [极客大挑战 2019]BuyFlag
  2. css伪元素::before与::after使用基础示例
  3. 关于WIN7系统,在运行pycharm时,老出现问题
  4. Spring DATA Neo4J(一)
  5. h5-渐变的基本描述
  6. uploadifive使用笔记
  7. 面向对象 / MVC
  8. linux 中的.so和.a文件
  9. GCC与G++区别
  10. 使用spark