Lock同步锁

Lock
在jdk1.5  提供了Lock以便执行同步操作,和synchronized不同的是Lock提供了显示的方法获取锁和释放锁。Lock提供了以下几个方法,请求和释放锁:
  • void lock()  
    获取锁,当前锁若是不可用的时候,此线程将休眠直到锁被获取到。
  • void lockInterruptibly()
    获取锁,当前锁若是不可用,此线程将休眠直到锁被获取。有两种情况线程不会休眠:
    1、当前线程获取了锁
    2、其他线程终止了当前线程,并且终止获取锁是被允许的。
  • boolean tryLock()
    获取锁,当前锁可用则返回'true',反之返回'false';使用方法如下:
    1. Lock lock = ...;
    2. if (lock.tryLock()) {
    3. try {
    4. // manipulate protected state
    5. } finally {
    6. lock.unlock();
    7. }
    8. } else {
    9. // perform alternative actions
    10. }
  • boolean tryLock(long,TimeUnit)
    获取锁,在规定的时间内,锁一直不可用返回'false',反之返回'true'
  • void unlock()
    释放锁。使用事项:此方法和获取锁的几个方法一一对应,获取到了锁,必须最后调用此方法释放锁。
  • Condition newCondition()
    获取一个Condition对象,操作当前锁。
使用原则 获取锁==>run()==>释放锁。这一原则和synchronized是一样的,只是获取和释放时是显示调用的,也是因为lock和unlock的组合使用,多个同步方法能很方便的嵌套使用,执行完后会依次释放自己所持有的锁。如下:
  1. Lock l = ...;
  2. l.lock();
  3. try{
  4. //do something
  5. } finally{
  6. l.unlock();
  7. }
通常锁提供了资源的独占访问,不过某些确实允许对资源的并发访问,如ReadWriteLock(读写锁),开发中常用的ReentantLock(可重入锁),比如下面使用方法:
  1. class X {
  2. private final ReentrantLock lock = new ReentrantLock();
  3. // ...
  4. public void m() {
  5. lock.lock(); // block until condition holds
  6. try {
  7. // ... method body
  8. } finally {
  9. lock.unlock()
  10. }
  11. }
  12. }

Condition
使用Lock替换了Synchronized实现同步操作时,Condition替换了Object 监视器方法的使用。
Conditions (也可以称为条件队列或者条件变量)为某些行为提供了用途,如一个线程需要等待,直到某些条件为ture,被其他线程唤醒。因为在不同线程里访问共享信息是必须受到保护,因此锁的状态根据某些条件决定的。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。
一个锁绑定了一个Condition对象。可以通过Lock的newCondition()方法获取。下面写了一个小例子:
  1. class BoundedBuffer {
  2. final Lock lock = new ReentrantLock();
  3. final Condition notFull = lock.newCondition();
  4. final Condition notEmpty = lock.newCondition();
  5. final Object[] items = new Object[100];
  6. int putptr, takeptr, count;
  7. public void put(Object x) throws InterruptedException {
  8. lock.lock();
  9. try {
  10. while (count == items.length)
  11. notFull.await();
  12. items[putptr] = x;
  13. if (++putptr == items.length) putptr = 0;
  14. ++count;
  15. notEmpty.signal();
  16. } finally {
  17. lock.unlock();
  18. }
  19. }
  20. public Object take() throws InterruptedException {
  21. lock.lock();
  22. try {
  23. while (count == 0)
  24. notEmpty.await();
  25. Object x = items[takeptr];
  26. if (++takeptr == items.length) takeptr = 0;
  27. --count;
  28. notFull.signal();
  29. return x;
  30. } finally {
  31. lock.unlock();
  32. }
  33. }
  34. }
方法描述:
Modifier and Type Method and Description
void await()
使当前线程处于等待状态,直到收到信号或者被打断.
boolean await(long time, TimeUnit unit)
在规定时间里使当前线程处于等待状态,直到在这段时间内收到信号或者被打断。。
long awaitNanos(long nanosTimeout)
在规定时间里使当前线程处于等待状态,直到在这段时间内收到信号或者被打断。
void awaitUninterruptibly()
使当前线程处于等待状态明知道收到信号。
boolean awaitUntil(Date deadline)
在规定时间里使当前线程处于等待状态,直到在这段时间内收到信号或者被打断。.
void signal()
唤醒一个正在等待的线程.
void signalAll()

补充
ReentrantLock 锁具有重入性,也就是说线程可以对它已经加锁的ReentrantLock锁再次加锁,ReentrantLock对象会维持一个计数器来跟踪lock方法的嵌套调用,线程在每次调用lock()加锁后,必须显式调用unlock()来释放锁,所以一段被锁保护的代码可以调用另一个被相同锁保护的方法。

最新文章

  1. plsql连接本地数据库
  2. Sublime Text 3 汉化小技巧
  3. Fluent NHibernate关系映射
  4. VS中引用第三方库的方法(配置sqlite数据库)
  5. HDU 2647
  6. TForm.ShowModal只是接管消息循环,禁止外部键盘和鼠标输入到别的窗口,但并不封锁其它窗口继续获取消息(比如WM_TIMER消息仍可被发送到别的窗口上)
  7. express4.x中路由中间件和挂载路径的关系
  8. 2017-3-9 SQL server 数据库
  9. 如何阻止sql注入(pdo篇)
  10. os常用模块,json,pickle,shelve模块,正则表达式(实现运算符分离),logging模块,配置模块,路径叠加,哈希算法
  11. CentOS 6安装配置mongodb
  12. 跟着未名学Office - 高效笔记OneNote
  13. ORACLE 几个我忍了他很多年的问题
  14. 安卓开发笔记——Broadcast广播机制(实现自定义小闹钟)
  15. struts2 正确配置通配符方式访问,报错解决
  16. 【C语言天天练(二二)】位操作
  17. JSON动态生成树
  18. ubuntu安装wineqq遇到错误
  19. System.arraycopy的测试
  20. d3.js 清除svg

热门文章

  1. 关于Array的map方法中回调函数参数的问题
  2. Linux下Steam中支持中文的办法
  3. 安装jhipster
  4. Mac下maven工程的创建,并搭建SSH环境
  5. 如何正确配置Nginx+PHP
  6. EST
  7. linux glances的基本使用
  8. 【bzoj4721】[Noip2016]蚯蚓
  9. Unix网络单词汇总
  10. .Net Framework认知