Condition JDK相关

转载 2012年03月28日 22:34:40
java.util.concurrent.locks 
接口 Condition
所有已知实现类: 
AbstractQueuedLongSynchronizer.ConditionObject, AbstractQueuedSynchronizer.ConditionObject 

--------------------------------------------------------------------------------

public interface ConditionCondition 将 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 实例来做到这一点。 

 class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length) 
         notFull.await();
       items[putptr] = x; 
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0) 
         notEmpty.await();
       Object x = items[takeptr]; 
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   } 
 }
 (ArrayBlockingQueue 类提供了这项功能,因此没有理由去实现这个示例类。) 
Condition 实现可以提供不同于 Object 监视器方法的行为和语义,比如受保证的通知排序,或者在执行通知时不需要保持一个锁。如果某个实现提供了这样特殊的语义,则该实现必须记录这些语义。 

注意,Condition 实例只是一些普通的对象,它们自身可以用作 synchronized 语句中的目标,并且可以调用自己的 wait 和 notification 监视器方法。获取 Condition 实例的监视器锁或者使用其监视器方法,与获取和该 Condition 相关的 Lock 或使用其 waiting 和 signalling 方法没有什么特定的关系。为了避免混淆,建议除了在其自身的实现中之外,切勿以这种方式使用 Condition 实例。 

除非另行说明,否则为任何参数传递 null 值将导致抛出 NullPointerException。 

实现注意事项
在等待 Condition 时,允许发生“虚假唤醒”,这通常作为对基础平台语义的让步。对于大多数应用程序,这带来的实际影响很小,因为 Condition 应该总是在一个循环中被等待,并测试正被等待的状态声明。某个实现可以随意移除可能的虚假唤醒,但建议应用程序程序员总是假定这些虚假唤醒可能发生,因此总是在一个循环中等待。 

三种形式的条件等待(可中断、不可中断和超时)在一些平台上的实现以及它们的性能特征可能会有所不同。尤其是它可能很难提供这些特性和维护特定语义,比如排序保证。更进一步地说,中断线程实际挂起的能力在所有平台上并不是总是可行的。 

因此,并不要求某个实现为所有三种形式的等待定义完全相同的保证或语义,也不要求其支持中断线程的实际挂起。 

要求实现清楚地记录每个等待方法提供的语义和保证,在某个实现不支持中断线程的挂起时,它必须遵从此接口中定义的中断语义。 

由于中断通常意味着取消,而又通常很少进行中断检查,因此实现可以先于普通方法的返回来对中断进行响应。即使出现在另一个操作后的中断可能会释放线程锁时也是如此。实现应记录此行为。 



从以下版本开始: 
1.5 

--------------------------------------------------------------------------------

方法摘要 
 void await() 
          造成当前线程在接到信号或被中断之前一直处于等待状态。 
 boolean await(long time, TimeUnit unit) 
          造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。 
 long awaitNanos(long nanosTimeout) 
          造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。 
 void awaitUninterruptibly() 
          造成当前线程在接到信号之前一直处于等待状态。 
 boolean awaitUntil(Date deadline) 
          造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。 
 void signal() 
          唤醒一个等待线程。 
 void signalAll() 
          唤醒所有等待线程。 
  

方法详细信息 



相关文章推荐

JDK 源码解析 —— Condition

一. 简介 使用 Condition 可以让线程等待不同条件,典型的例子就是 ArrayBlockingQueue。 二. 源码解析 Condition 接口的具体实现是...

生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版

生产者消费者模型(多个生产者和多个消费者)JDK1.5 (Lock&Condition)实现版场景描述多线程开发中很经典的一个案例就是生产者消费者模型,它们共享资源,但是对资源的操作方式并不同。因此它...

JDK1.5之后怎么玩转多线程(Lock和Condition的使用)

在JDK1.5之前同步使用的是Synchronized的方法,而线程的通信使用的是wait、Notify、NotifyAll等方法, 那么1.5之后就可以使用新的类库 Lock、Condition来完...

JDK5 condition线程通信

JDK5之后提供了Lock 和 Condition俩个对象完全可以取代synchronized和wait、notify关键字。  下面实现一个例子说明线程通信.(主次线程交替运行10次)。    ...

jdk 源码分析(12)java condition 条件锁

condition 用一个链表(Node)队列(FIFO)缓存wait,通过争论waitstute来改变状态,通过park和unpark来释放和等待...

使用jdk1.5的多线程 lock condition 实现方式实现 生产者消费者问题

import java.util.concurrent.locks.*; //描述产品 class Clothes { //产品名称 private String name; //产品价格...

centos7 jdk(java) 安装以及安装命令相关知识

本文经过我的亲手实践,完全通过,但是参考了大量网上他人共享的知识,在此说声谢谢,写的过程中我没有留下他们的url,抱歉! centos7 jdk(java)安装步骤: 1.检查系统原有版本 ja...

几个与JVM相关的JDK工具:jps, jstat, jmap

几个与JVM相关的JDK工具:jps, jstat, jmap 几个与JVM相关的JDK工具:jps, jstat, jmap 在项目中遇到OOM(Out of Memory)的问题,...

JDK源码阅读 java.util.concurrent.Executors相关分析

在jdk的java.util.concurrent,提供了Executor相关的类来帮助我们创建线程并管理线程的执行顺序。 1.类之间的关系 与java执行器相关的类有:Executor ,Exe...
  • rommel1
  • rommel1
  • 2012年02月26日 23:43
  • 3623

JDK相关问题汇总

【JDK各个文件夹的作用】 一:bin:        JDK中所包含的开发工具的可执行文件,path环境变量应该包含一个指向此目录的项。书中是这样说的:一些命令行工具,包括Java编译器的启动命...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Condition JDK相关
举报原因:
原因补充:

(最多只允许输入30个字)