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. 2 django系列之django分页与templatetags

    preface 当页面出现的条目多的时候,我们就需要使用分页功能了.Django作为一个知名的web框架,自然也提供了分页功能,下面说说它. Python-shell 练练手 在python下入手 先 ...

  2. 将一张表的数据,拷贝到另一张表中sql

    两张表的字段一样 create table 目标表 as  select * from 原表;

  3. SecureCRT上传和下载文件

    SecureCRT上传和下载文件(下载默认目录) SecureCR 下的文件传输协议有ASCII .Xmodem .Ymodem .Zmodem ASCII:这是最快的传输协议,但只能传送文本文件. ...

  4. Django基础,Day6 - 单元测试tests

    在django项目app目录下,有个tests.py,我们通常可以直接在这文件中写我们的单元测试代码. test for a model 根据前面章节的操作步骤下来,在Question Model中有 ...

  5. 【jQuery】初始化的三种方法

    JQ初始化方法实际上有两种,由于美元符号可以定义 jQuery,那么就有三种方法可以进行初始化操作,根据个人习惯来选择吧! 第一种 $(document).ready(function(){ // j ...

  6. JS中用apply、bind实现为函数或者类传入动态个数的参数

    为纪念10年没写blog,第一篇博文就以这样一个有趣的窍门开始吧 -___- 在ES5中,当我们调用一个函数时,如果要传入的参数是根据其他函数或条件判断生成的,也就是说不确定会传入多少个参数时,在不改 ...

  7. 3D游戏编程大师技巧──2D引擎的编译问题

    接上一篇文章,这里将介绍2D引擎的编译,从现在开始才真正进入<3D游戏编程大师技巧>的学习.本书的第一.二章只是简介了游戏编程和windows编程,从第三章开始才是介绍<window ...

  8. HDOJ 1358

    Period Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  9. 第4月第2天 nsinvocation崩溃 mvc videotrack

    1. __unsafe_unretained id result = nil; [invocation getReturnValue:&result]; return result; http ...

  10. JS判断字符串长度(中文长度为2,英文长度为1)

    目的:计算字符串长度(英文占1个字符,中文汉字占2个字符) 方法一: String.prototype.gblen = function() { var len = 0; for (var i=0; ...