8、Condition

java.util.concurrent.locks

Interface Condition

Condition类似于传统的wait、notify/notifyAll方法(这些方法需要内部监听器)。

Condition是在Lock之下,换句话说,有了Lock才可能产生Condition。在一个Lock之下可以生成几个Condition,从而可以使得因某个

Condition而阻塞的线程只能由相应的Condition唤醒。

比如,假设我们拥有一个支持取数据(take)和写数据(put)的缓存。如果take方法操作一个空的缓存,线程将会阻塞直到缓存中有数据项可用;

如果put方法试图操作一个满的缓存,线程将会阻塞知道用可用的空间。

 1 class BoundedBuffer {
 2        final Lock lock = new ReentrantLock();
 3        final Condition notFull  = lock.newCondition();
 4        final Condition notEmpty = lock.newCondition();
 5
 6        final Object[] items = new Object[100];
 7        int putptr, takeptr, count;
 8
 9        public void put(Object x) throws InterruptedException {
10          lock.lock();
11          try {
12            while (count == items.length)
13              notFull.await();
14            items[putptr] = x;
15            if (++putptr == items.length) putptr = 0;
16            ++count;
17            notEmpty.signal();
18          } finally {
19            lock.unlock();
20          }
21        }
22
23        public Object take() throws InterruptedException {
24          lock.lock();
25          try {
26            while (count == 0)
27              notEmpty.await();
28            Object x = items[takeptr];
29            if (++takeptr == items.length) takeptr = 0;
30            --count;
31            notFull.signal();
32            return x;
33          } finally {
34            lock.unlock();
35          }
36        }
37 }

程序分析:

1、这里设置了两个条件notFull、notEmpty,当容器满了,就不满足notFull了,因此notFull.await,使得线程阻塞;notFull条件的阻塞,只能由notFull条件唤醒。

同理,notEmpty,当容器为空的时候,就不满足条件notEmpty了,因此notEmpty.await,使得线程阻塞,notEmpty条件的阻塞,只能由notEmpty条件唤醒。

2、判断边界值,从而判断条件是否满足,用的是while而不能是if。这是因为当线程被唤起后,还要检测条件是否满足,如果用if就不能达到这种效果,而会产生意想不到的

情况。比如,假设现在容器的大小为5。此时有10个写数据的线程来写数据,前面5个写线程都能正常往容器里面写数据,当容器满了以后接下来的线程就会不满足条件

notFull而放弃锁等待(await),因此会有5个线程阻塞于此。如果现在调用notFull.singalAll方法将所有不满足notFull条件而阻塞的线程都唤醒,那么缓存就会比它固定大小

多4个(造成缓存溢出)。当然,现在如果仅仅是调用的notFull.single,之所以会执行到这一步就是因为已经消费了而且只能唤醒一个线程,那么肯定会满足notFull条件,没有必要去进行检查。

时间: 2024-08-30 07:24:48

8、Condition的相关文章

【Java线程】锁机制:synchronized、Lock、Condition

http://www.infoq.com/cn/articles/java-memory-model-5  深入理解Java内存模型(五)——锁 http://www.ibm.com/developerworks/cn/java/j-jtp10264/  Java 理论与实践: JDK 5.0 中更灵活.更具可伸缩性的锁定机制 http://blog.csdn.net/ghsau/article/details/7481142 1.synchronized 把代码块声明为 synchronize

Synchronized、lock、volatile、ThreadLocal、原子性总结、Condition

1. Synchronized 首先Synchronized锁住的是对象 1.1 互斥:两个线程去调用同一对象的synchronized代码块,只有一个线程能够获得锁,另个线程会被阻塞 1.2 共享:类中有多个Synchronized代码块,这些代码块共享对象上同一个锁,即类中有Synchronized方法f().g(),如果有一个线程获得了对象上的锁,调用f()方法,另个线程调用该对象g()需要等待前一个线程执行完f()函数 1.3 可重入性:JVM跟踪对象被加锁的次数,同一个线程可以多次获得

Java线程 synchronized、Lock、Condition

java.util.concurrent.lock 中的Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现.这就为Lock 的多种实现留下了空间,各种实现可能有不同的调度算法.性能特性或者锁定语义. ReentrantLock 类实现了Lock ,它拥有与synchronized 相同的并发性和内存语义,但是添加了类似锁投票.定时锁等候和可中断锁等候的一些特性.此外,它还提供了在激烈争用情况下更佳的性能.(换句话说,当许多线程都想访问共享资源时,JV

多线程(十一、AQS原理-ReentrantLock的条件队列Condition)

1.Condition介绍 1.1 Condition是对线程的wait,notify的增强 1.2 在ReentrantLock中他的实现类是AQS中的ConditionObject,实现了Condition接口,利用AQS的节点,实现了条件队列. 2.案例分析 2.1 说明:Thread-1获取锁,然后await,释放锁:Thread-2获得锁,唤醒Thread-1,释放锁:Thread-1重新获取锁,释放锁. 2.2 代码 2.2.1 Thread-1 import java.util.c

Spring使用Cache、整合Ehcache

从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回.所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果. 使用Spring Cache需要我们做两方面的事: n  声明

【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比较简单,但是一定要理解. 有几个概念一定要牢记: 加锁必须要有锁 执行完后必须要释放锁 同一时间.同一个锁,只能有一个线程执行 二.synchronized synchronized的特点是自动释放锁,作用在方法时自动获取锁,任意对象都可做为锁,它是最常用的加锁机制,锁定几行代码,如下: //---

java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)

一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.concurrent.locks.ReentrantLock 锁,JDK也为我们提供了与此功能相应的类java.util.concurrent.locks.Condition.Condition与重入锁是通过lock.newCondition()方法产生一个与当前重入锁绑定的Condtion实例,我们

线程基础知识系列(四)线程的同步2 线程通信和Condition变量

本文是系列的第四篇. 线程基础知识系列(三)线程的同步  :同步控制,锁及synchronized 线程基础知识系列(二)线程的管理 :线程的状态,控制,休眠,Interrupt,yield等 线程基础知识系列(一)线程的创建和启动  :线程的创建和启动,join(),daemon线程,Callable任务. 第三篇文章,重点阐述了如何使用锁和同步块对线程间共享可变变量保护,保证只有一个线程可以进入临界区.其实,没有过多的涉及另一个重要的同步概念:线程协作.第三篇中涉及的线程间并没有有效的协调.

Python高级编程 面向对象、元类、多线程、异步IO、asyncio

—— 面向对象 —— 鸭子类型抽象基类类变量.对象变量的查找顺序静态方法.类方法.实例方法数据封装和私有属性对象的自省机制上下文管理器contextlib实现上下文管理器super函数的查找顺序mixin继承模式的应用 —— asyncio并发编程 —— 事件循环协程嵌套call_soon.call_later.call_atcall_soon_threadsafeThreadPoolExecutor+asyncioasyncio 模拟 http 请求future 和 taskasyncio 同