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. js loaclstorage和sessionstorage

    这里需要注意的是这两种储存方式只能以字符串的形式来存取 html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage.sessionStorage用于 ...

  2. [Java] JSP笔记 - 自定义标签

    自定义标签的创建步骤: 自定义标签的四大功能: 自定义标签的类结构: 在 1.0 中呢, 可以将 <body-content> 的值设置为 JSP, 2.0中则不允许在自定义标签体中出现j ...

  3. SQL2008 无日志附加MDF文件

    SQL数据在附加的时候..有时会因为日志文件过大..或者一些其他问题造成附加失败.. 笔者遇到的问题是数据库主文件(*.mdf)超过25G..日志文件超过200G..附加的耗时简直日了狗了..最后超时 ...

  4. nginx安装与配置

    一.在线安装 ubuntu 安装 sudo apt-get install nginx 安装后文件结构为: 配置文件:/etc/nginx ,并且每台虚拟主机已经安排在 /etc/nginx/site ...

  5. HttpContext.Cache属性

    HttpContext基于HttpApplication的处理管道,由于HttpContext对象贯穿整个处理过程,所以,可以从HttpApplication处理管道的前端将状态数据传递到管道的后端, ...

  6. linux查看端口及端口详解

    今天现场查看了TCP端口的占用情况,如下图   红色部分是IP,现场那边问我是不是我的程序占用了tcp的链接,,我远程登陆现场查看了一下,这种类型的tcp链接占用了400多个,,后边查了一下资料,说E ...

  7. C# Async, Await and using statements

    Async, Await 是基于 .NEt 4.5架构的, 用于处理异步,防止死锁的方法的开始和结束, 提高程序的响应能力.比如: Application area           Support ...

  8. SqlDataReader和SqlDataAdapter

    SqlDataReader 高效,功能弱,只读访问SqlDataAdapter 强大,要求资源也大一点 SqlDataReader 只能在保持跟数据库连接的状态下才可以读取... SqlDataAda ...

  9. 07-本地 YUM 源制作

    1.YUM相关概念 1.1.什么是YUM YUM(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基 ...

  10. 转载:Centos7 从零编译配置Memcached

    序言 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度. Memca ...