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()来释放锁,所以一段被锁保护的代码可以调用另一个被相同锁保护的方法。

四、线程同步之Lock和Condition的更多相关文章

  1. Python并行编程(三):线程同步之Lock

    1.基础概念 当两个或以上对共享内存操作的并发线程中,如果有一个改变数据,又没有同步机制的条件下,就会产生竞争条件,可能会导致执行无效代码.bug等异常行为. 竞争条件最简单的解决方法是使用锁.锁的操 ...

  2. Python之路(第四十五篇)线程Event事件、 条件Condition、定时器Timer、线程queue

    一.事件Event Event(事件):事件处理的机制:全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么 ...

  3. 扯扯python的多线程的同步锁 Lock RLock Semaphore Event Condition

    我想大家都知道python的gil限制,记得刚玩python那会,知道了有pypy和Cpython这样的解释器,当时听说是很猛,也就意味肯定是突破了gil的限制,最后经过多方面测试才知道,还是那德行… ...

  4. 线程同步 – lock和Monitor

    在多线程代码中,多个线程可能会访问一些公共的资源(变量.方法逻辑等等),这些公共资源称为临界区(共享区):临界区的资源是不安全,所以需要通过线程同步对多个访问临界区的线程进行控制. 同样,有些时候我们 ...

  5. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  6. C#当中的多线程_线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

  7. windows线程同步的总结

    一 线程 1)如果你正在编写C/C++代码,决不应该调用CreateThread.相反,应该使用VisualC++运行期库函数_beginthreadex,退出也应该使用_endthreadex.如果 ...

  8. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  9. Lock和Condition

    1 什么是可重入锁 可重入锁是说一个线程在已经获取了该锁的情况下,还可以再次获取该锁. 主要的应用场景: 可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又 ...

随机推荐

  1. 02. Let & Const

    Let & Const let 基础用法 很简单就能说明这个问题 if(false) { var a = 'heihei' } a = undefined if(true) { var a = ...

  2. 写了个项目 Web-Rtmp: 使用 WebSocket 在网页上播放 RTMP 直播流

    http://neue.v2ex.com/t/316766 虽说浏览器里用 js 解码'播放'视频的方案已经有几个了... 为什么不再多一个呢... 基本原理: 服务端使用 websockify 中转 ...

  3. JVM:查看java内存情况命令

    jmap (linux下特有,也是很常用的一个命令) 观察运行中的jvm物理内存的占用情况. 参数如下: -heap :打印jvm heap的情况 -histo: 打印jvm heap的直方图.其输出 ...

  4. git 命令操作

    git add .   : 将所有修改过的工作文件提交暂存区 git commit -am 'new'  : 将修改过的文件进行记录 git push origin dev : 将项目推送到dev分只 ...

  5. js常用字符串处理方法

    JS自带函数concat将两个或多个字符的文本组合起来,返回一个新的字符串.var a = "hello";var b = ",world";var c = a ...

  6. js设置鼠标悬停改变背景色

    看了网上那么多的js鼠标悬停时事件,大多数的,说了那么多话,也没解决什么问题,现在直接贴上代码,以供参考 html: <div id="sign">this is te ...

  7. 【linux使用】bash shell命令行常用快捷键 (转载)

    移动: Ctrl + A: 移动到当前编辑的命令行首, Ctrl + E: 移动到当前编辑的命令行尾, Ctrl + F 或 ->:按字符右移(往命令行尾部方向,前移) Ctrl + B 或 & ...

  8. JS/CSS收藏

    jQuery radio取值,checkbox取值,select取值 var url += '&beginTime=' + encodeURIComponent(beginTime) if ( ...

  9. 初识java泛型

    1 协变数组类型(covariant array type) 数组的协变性: if A IS-A B then A[] IS-A B[] 也就是说,java中的数组兼容,一个类型的数组兼容他的子类类型 ...

  10. 转DNS DLZ +MYSQL

    关于bind的软件介绍这里就不讲解了 大家都知道是干嘛的  这里多介绍一下DLZ这个东西 大家都知道维护bind的时候 如果想新增一个zone 需要vim 编辑添加 这样.....然后bind启动后从 ...