`
cuisuqiang
  • 浏览: 3959006 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
3feb66c0-2fb6-35ff-968a-5f5ec10ada43
Java研发技术指南
浏览量:3669064
社区版块
存档分类
最新评论

Condition 条件变量,线程通信更高效的方式

    博客分类:
  • JDK
阅读更多

条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 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不知道唤醒的是读线程还是写线程了,如果唤醒的是读线程,皆大欢喜,如果唤醒的是写线程,那么线程刚被唤醒,又被阻塞了,这时又去唤醒,这样就浪费了很多时间!

 

请您到ITEYE网站看 java小强 原创,谢谢!

http://cuisuqiang.iteye.com/ 

自建博客地址:http://www.javacui.com/ ,内容与ITEYE同步!

分享到:
评论

相关推荐

    用成员变量进行线程通信.rar_线程通信

    5. **条件变量(Condition)**:Java `java.util.concurrent.locks.Condition`接口提供了更灵活的等待/通知机制,比简单的`wait()`和`notify()`更具有针对性。 6. **原子变量(Atomic Variables)**:如`...

    多线程之条件变量

    在多线程编程中,条件变量(Condition Variables)是一种重要的同步机制,用于线程间的通信和协调。条件变量允许线程在满足特定条件时挂起执行,等待其他线程改变状态,然后再唤醒继续执行。这种方式使得线程可以...

    多线程之间的线程通信

    总的来说,理解和掌握多线程之间的线程通信是编写高效、可靠并发程序的基础。通过合理设计和使用各种通信机制,我们可以创建出能够充分利用系统资源、处理复杂逻辑的多线程应用程序。在实际项目中,应始终关注线程...

    Linux系统编程-(pthread)线程通信(条件变量).pdf

    【Linux系统编程——pthread线程通信(条件变量)】 在多线程编程中,线程间的通信是非常重要的,条件变量(Condition Variables)是POSIX线程(pthread)库提供的一种同步机制,它允许线程在特定条件满足时才能继续...

    Java 线程通信示例 源代码

    4. **条件变量(Condition)**:在`java.util.concurrent.locks`包中,`ReentrantLock`提供了一种更细粒度的控制,允许创建多个条件变量,每个条件变量对应一种等待状态。线程可以在特定条件下等待,直到其他线程...

    进程线程通信,线程同步,异步,进程通信经典进程间通信.7z

    常见的线程同步方法包括互斥锁(Mutex)、信号量(Semaphore)、条件变量(Condition Variable)等。例如,互斥锁确保同一时间只有一个线程可以访问资源,防止数据竞争。 **异步**和**同步**是两种不同的执行模式。...

    linux无亲缘关系间进程同步通信实现(互斥锁+条件变量+共享内存模式)

    共享内存是一种高效的进程间通信方式,它允许多个进程直接访问同一块内存区域。通过`shmget`创建共享内存,`shmat`将其映射到进程地址空间,`shmdt`则用于取消映射。为了防止多个进程同时访问同一数据,通常会结合...

    C++实现多线程通信

    在C++编程中,多线程通信是并发执行任务时必不可少的一个环节,它涉及到线程间的同步和数据共享。在本篇文章中,我们将深入探讨如何在C++中实现多线程通信,以及相关的同步机制和数据交换策略。 一、线程创建与管理...

    图书管理线程通信问题

    在IT领域,线程通信是多...理解并正确使用各种线程通信机制,可以保证系统的高效、稳定和数据一致性。在实际开发过程中,我们需要根据具体需求选择合适的方法,并充分考虑并发情况下的线程安全,避免数据竞争和死锁。

    vc线程通信实现计时器

    5. **条件变量**:在C++标准库中,`std::condition_variable`提供了一种等待条件满足的机制。线程A可以等待某个条件变为真,而线程B可以通过改变条件来唤醒线程A。 现在,让我们专注于如何实现“计时器”这一功能。...

    多线程_sometimelrz_examine9j3_多线程通信_

    在IT领域,多线程通信是一项关键的技术,尤其在客户端-服务器架构中,它使得程序能够同时处理多个请求,提高系统效率和响应速度。本文将深入探讨多线程通信的概念、重要性以及实现方法。 首先,多线程是指在一个...

    linux条件变量简单讲解.pdf

    条件变量通常与互斥锁(mutex)一起使用,以避免竞争条件(Race Condition)和确保线程间的同步。本篇讲解将详细介绍Linux条件变量的基本概念、使用方法及其相关函数。 首先,条件变量是一种线程间通信的同步机制,...

    多线程编程中条件变量和虚假唤醒(spurious wakeup)的讨论

    在多线程编程中,条件变量(Condition Variables)是一个重要的同步机制,用于线程间的通信和协调。条件变量允许线程等待某个特定条件的发生,并在条件满足时被其他线程唤醒。然而,条件变量存在一个特性,即虚假...

    CVI 04.多线程数据保护(安全变量

    常见的安全变量包括互斥量(Mutex)、信号量(Semaphore)、条件变量(Condition Variable)以及原子操作(Atomic Operations)。 1. **互斥量**:互斥量是一种同步原语,用于确保同一时间只有一个线程能访问特定的...

    使用全局对象进行线程间的通信

    在使用全局变量进行线程通信时,通常需要配合这些同步原语来确保数据的一致性。 举个例子,假设我们有一个全局变量`g_counter`,两个线程`ThreadA`和`ThreadB`都需要修改这个计数器。为了保证安全,我们需要在修改`...

    线程同步(信号量,互斥,条件变量)

    **条件变量(Condition Variables)**用于线程间的异步通信,它允许线程等待某个特定条件满足后再继续执行。条件变量通常与互斥量结合使用,线程在等待条件时会释放互斥量,然后被挂起,当条件满足时,其他线程可以...

    操作系统中多线程之间通信

    在操作系统中,有多种实现线程通信的方式: 1. **信号量(Semaphore)**:信号量是一种计数器,可以用于限制同时访问某个资源的线程数量。它可以是二进制信号量(只能取0或1,类似互斥锁)或计数信号量(可取大于1...

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

    C++多线程中的锁和条件变量使用教程 在C++多线程编程中,锁和条件变量是两个非常重要的概念,它们都是用于解决多线程之间的同步和通信问题的。...通过使用锁和条件变量,我们可以编写更加安全、更加高效的多线程程序。

    C++ 多线程通信方式简介并结合生产者-消费者模式代码实现

    本文将深入探讨C++中的多线程通信方式,并结合经典的生产者-消费者模式来阐述其实现。 一、C++多线程基础 C++11引入了标准库`<thread>`,提供了对多线程的支持。创建线程的基本方法是通过`std::thread`类,如下所示...

Global site tag (gtag.js) - Google Analytics