`
qindongliang1922
  • 浏览: 2148472 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:116348
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:124617
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:58495
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:70385
社区版块
存档分类
最新评论

Condition 条件变量的使用

阅读更多
条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样



在Condition中,用await()替换wait(),用signal()替换notify(),用signalAll()替换notifyAll(),传统线程的通信方式,Condition都可以实现。
条件变量类似JDK1.4或以前版本中的 Object.wait(); Object.notify(); Object.notifyAll();
值得注意的是当condition.await()时,隐式的将条件变量关联的Lock解锁,而使其他线程有机会获得Lock,而检查条件,并在条件满足时,等待在条件变量上。

示例代码,ArrayBlockingQueue源码摘取:


    /** Main lock guarding all access */  
    private final ReentrantLock lock;  
    /** Condition for waiting takes */  
    private final Condition notEmpty;  
    /** Condition for waiting puts */  
    private final Condition notFull;  
    /** 
     * Inserts the specified element at the tail of this queue, waiting 
     * for space to become available if the queue is full. 
     * 
     * @throws InterruptedException {@inheritDoc} 
     * @throws NullPointerException {@inheritDoc} 
     */  
    public void put(E e) throws InterruptedException {  
     if (e == null) throw new NullPointerException();  
     final E[] items = this.items;  
     final ReentrantLock lock = this.lock;  
     lock.lockInterruptibly();  
     try {  
      try {  
       while (count == items.length)  
        notFull.await();  
      } catch (InterruptedException ie) {  
       notFull.signal(); // propagate to non-interrupted thread  
       throw ie;  
      }  
      insert(e);  
     } finally {  
      lock.unlock();  
     }  
    }  
    public E take() throws InterruptedException {  
     final ReentrantLock lock = this.lock;  
     lock.lockInterruptibly();  
     try {  
      try {  
       while (count == 0)  
        notEmpty.await();  
      } catch (InterruptedException ie) {  
       notEmpty.signal(); // propagate to non-interrupted thread  
       throw ie;  
      }  
      E x = extract();  
      return x;  
     } finally {  
      lock.unlock();  
     }  
    }  



有多个线程往里面存数据和从里面取数据,其队列(先进先出后进后出)能缓存的最大数值是capacity,多个线程间是互斥的,当缓存队列中存储的值达到capacity时,将写线程阻塞,并唤醒读线程,当缓存队列中存储的值为0时,将读线程阻塞,并唤醒写线程
这就是多个Condition的强大之处,假设缓存队列中已经存满,那么阻塞的肯定是写线程,唤醒的肯定是读线程,相反,阻塞的肯定是读线程,唤醒的肯定是写线程,那么假设只有一个Condition会有什么效果呢,缓存队列中已经存满,这个Lock不知道唤醒的是读线程还是写线程了,如果唤醒的是读线程,皆大欢喜,如果唤醒的是写线程,那么线程刚被唤醒,又被阻塞了,这时又去唤醒,这样就浪费了很多时间!


本篇非原创转自:http://cuisuqiang.iteye.com/blog/2019251
分享到:
评论

相关推荐

    C++跨平台条件变量和互斥锁封装

    用C++封装的跨平台条件变量和互斥量,windows环境和linux环境都测试好用, 是理解条件变量和互斥量的好demo。

    Python线程条件变量Condition原理解析

    这篇文章主要介绍了Python线程条件变量Condition原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Condition 对象就是条件变量,它总是与某种锁相关联,...

    C++多线程中的锁和条件变量使用教程

    多线程间的状态同步,这个可用的机制很多,条件变量是广泛使用的一种。 今天我用一个简单的例子来给大家介绍下锁和条件变量的使用。 代码使用C++11 示例代码 #include #include #include #include <condition> ...

    python条件变量之生产者与消费者操作实例分析

    Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后...

    condition_variable源码以及详细分析.docx

    详细介绍了线程同步条件变量condition_variable的使用和它的源码,涉及到unique_lock, mutex, lock_guard, 虚假唤醒和惊群效应。

    zm_condition_variable.zip

    由于glibc早期版本的实现方式问题,导致在linux平台上使用c++条件变量(condition variable)时如果发生系统时间修改或跳变(向前),导致wait超时机制会阻塞,所以用select实现了一套跨平台的条件变量,已在项目中自测...

    Python多线程编程(七):使用Condition实现复杂同步

    目前我们已经会使用Lock去对公共资源进行互斥访问了,也探讨了同一线程可以使用RLock...使用Condition的主要方式为:线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处

    C++11 并发指南五(stdcondition_variable 详解).docx

    C++11 并发指南五(stdcondition_variable 详解).docx

    6. 通知状态的改变—C++条件变量1

    是
C++
中的
condition_variable
却只有默认的构造函数//
直接初始化即可使用同样地,condition_variable
对象必须搭配互

    python 多线程的同步机制 以python2例程的方式讲解了python 多线程的同步 常用的方法,主要是锁、条件同步、队列

    python 多线程的同步机制 以... 所以如果使用了锁、条件变量等同步机制的话,一定要注意仔细检查,防止死锁情况的发生。  保证每一个wait()方法调用都有一个相对应的notify()调用,当然也可以调用notifyAll()方法以

    locks框架:接口.pdf

    Condition 条件变量: 介绍 Lock 接口中的 Condition,它可以实现更复杂的线程等待和通知机制。解释如何使用 await、signal 和 signalAll 方法。 通过这份资源,您将获得关于 Locks 框架中 Lock 接口的深入理解,从...

    <二>、C++实现多线程的同步处理:控制ABC的输出顺序,输出10组,mutex+condition-variable源码示例

    这个使用条件变量的方式,跟标志位有异曲同工之妙,并且不用来回变来变去的,只需要计数器不停递增即可。和之前没啥区别,不过效果更好控制,逻辑更简单易控。接着上一篇,本篇实现更复杂一些的条件变量的处理。 ...

    MyBatis拦截器 添加查询条件动态修改sql

    通过mybatis的拦截器,实现为所有sql(或指定sql) 统一添加查询条件,譬如通过线程变量传递某参数(日期),来实现对指定参数的数据筛选,而不需要在每个查询前,手动将该条件注入到查询中。因该资料网络较少,故特此...

    linux之线程同步一.doc

    linux之线程同步一 在Linux中,线程同步是一种控制多个线程...3. **条件变量(Condition Variables)**:条件变量通常与互斥锁一起使用,允许一个或多个线程等待某个条件成立,直到其他线程通知它们条件已经满足。这种

    ConditionWait.tar.gz

    使用条件变量域互斥锁来同步生产者和消费者之间访问临界区数据问题,大幅降低CPU占用率问题。

    Python threading模块condition原理及运行流程详解

    首先acquire一个条件变量,然后判断一些条件。 如果条件不满足则wait; 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。 不断的重复这一...

    python八股文+源码

    其中, `variable_name` 是变量的名称, `value` 是变量的值。Python的变量可以保存任何类型的数据,包括数字、字符串、列表、字典等等。 1. 条件语句 条件语句是Python程序中的一种基本结构,用于根据某些条件来...

    Python线程协作threading.Condition实现过程解析

    # 条件变量,用于复杂的线程间同步锁 """ 需求: 男:小姐姐,你好呀! 女:哼,想泡老娘不成? 男:对呀,想泡你 女:滚蛋,门都没有! 男:切,长这么丑, 还这么吊... 女:关你鸟事! """ class Boy(threading.Thread): def ...

Global site tag (gtag.js) - Google Analytics