本文基本是JDK文档中的说明内容,但是已经很好的解释了Condition对象的使用方法。
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并挂起当前线程,就像 Object.wait 做的那样。
Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。
作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。
代码实例:
package com.mutex; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 实现自己的阻塞队列 */ public class MyBlockingQueue<T> { private final Lock lock = new ReentrantLock(); private Condition notFull = lock.newCondition(); private Condition notEmpty = lock.newCondition(); private final Object[] items = new Object[100]; private int putptr, takeptr, count; public void put(T x) { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = 0; ++count; notEmpty.signal(); } catch (InterruptedException e) { // todo } finally { lock.unlock(); } } public T take() { lock.lock(); try { while (count == 0) notEmpty.await(); T x = (T) items[takeptr]; if (++takeptr == items.length) takeptr = 0; --count; notFull.signal(); return x; } catch (InterruptedException e) { // todo return null; } finally { lock.unlock(); } } public static void main(String[] args) { final MyBlockingQueue<String> bq = new MyBlockingQueue<String>(); new Thread() { public void run() { int count = 0; while (true) { ++count; bq.put("test: " + count); } } }.start(); new Thread() { public void run() { while (true) { System.out.println(bq.take()); } } }.start(); } }
相关推荐
#### 二、Java并发核心概念 在深入讨论具体技术细节之前,我们先了解一些关键的Java并发概念: 1. **Java Memory Model (JMM)**: - **定义**: 在Java SE 5 (JSR133)中引入的Java Memory Model (JMM)旨在确保编写...
3. **锁**:Java并发库中的`java.util.concurrent.locks`包提供了更高级的锁机制,如可重入锁(`ReentrantLock`)、读写锁(`ReadWriteLock`)和条件变量(`Condition`),这些工具允许更灵活的控制并发访问。 4. **并发...
通过阅读和分析这些代码,我们可以深入理解Java并发API的用法,如`java.util.concurrent`包下的工具类和接口。 2. **ListenerExamples.java**:此文件可能涉及到事件驱动编程和监听器模式,这是GUI编程中常见的并发...
Java Locks框架是Java并发编程中的重要组成部分,它提供了一种比传统的`synchronized`关键字更为灵活和可控的线程同步机制。Lock接口是这个框架的核心,它的出现使得开发者能够更精确地控制对共享资源的访问,从而...
Java并发编程是指在Java语言中编写多线程和多任务执行的程序,以便更高效地利用计算机的多核处理器资源。并发编程是Java高级编程技能中的重要组成部分,尤其是在需要处理大量数据、提供快速响应、实现高吞吐量和高可...
Condition接口是Java并发编程中实现等待/通知模式的重要工具。它提供了灵活的等待/通知机制,允许线程在特定条件不满足时挂起,并在条件满足时被唤醒。通过使用Condition,我们可以编写出更高效、更可靠的并发程序。...
Java并发编程是Java开发中的重要领域,它涉及到多线程、同步、锁机制、线程池等关键概念,是提高程序性能和效率的关键技术。在Java中,并发编程的运用可以充分利用多核处理器的能力,实现高效的多任务处理。以下是对...
《Java 并发编程实战》是一本专注于Java并发编程领域的权威书籍,旨在帮助开发者深入理解和掌握在多线程环境中编写高效、安全且可维护的代码。这本书涵盖了Java并发编程的基础概念,高级特性以及最佳实践,是Java...
在Java并发编程中,尤其是在处理多线程同步时,一个重要的概念是“虚假唤醒”(Spurious Wakeup)。这是一种较为罕见的现象,但在实际开发过程中仍然值得高度关注。虚假唤醒指的是,在没有其他线程调用`notify()`...
《实战Java高并发程序设计》是一本专注于Java并发编程的经典文献,它深入浅出地讲解了如何在Java环境中处理高并发场景。这本书是PDF格式,包含详细的目录,方便读者快速定位到所需的知识点,是Java开发者提升并发...
《Java并发编程实践》这本书深入探讨了Java平台上的并发编程技术,是Java开发者提升多线程编程能力的重要参考资料。在Java编程中,并发是提高系统性能、实现高并发处理的关键技术,尤其在如今多核处理器普及的时代,...
Java并发工具类是Java平台提供的一系列用于处理多线程并发问题的类和接口,它们在`java.util.concurrent`包中。并发问题主要包括资源竞争、死锁、活锁以及饥饿等,合理使用并发工具可以有效地提高程序的并发性能并...
《Java并发编程实战》是Java开发者深入理解并发编程的一本重要参考书,它详细阐述了如何在多线程环境中设计、实现和优化程序。这本书基于Java平台,涵盖了从基础概念到高级特性的全面内容,旨在帮助读者掌握Java并发...
Lock锁是Java并发库中的一个核心组件,位于java.util.concurrent.locks包下。相比传统的synchronized关键字,Lock提供了更细粒度的控制,具有更高的灵活性。Lock接口包括以下方法: 1. lock():获取锁,如果锁被...
Java并发编程是Java开发中的重要领域,特别是在多线程应用中,锁机制是保障线程安全、实现资源有效管理的关键工具。本资料“Java并发锁简介-动力节点共9页.pdf.zip”似乎提供了关于Java并发锁的基础介绍。下面将详细...
`ReentrantLock`是Java并发编程中的一种重要工具,它允许线程在已经获取锁的情况下再次获得同一把锁,而不必等待解锁。这在处理递归调用或嵌套锁的场景中特别有用。`ReentrantLock`提供了一种可选的公平策略,即线程...