`

CountDownLatch介绍3-之Condition

 
阅读更多
Condition只是一个接口,怎么可以直接调用它的方法呢?于是查源码(发现这个东西才是最彻底的),从ReentrantLock开始,
ReentrantLock.newCondition()
->Sync.newCondition() Sync是一个静态抽象的内部类
->ConditionObject 看来这个类最终实现了Condition接口
->AbstractQueuedSynchronizer.ConditionObject 抓到了
看到了详细的方法实现 ^_^

1.两三个线程同时修改某个对象,如果仅由访问先后来决定结果的话,会出现各种结果。这种情况被称为racecondition。

2. 防止这种情况的发生,必须知道如何同步访问(synchronize theaccess)。

3. javap -c -v ClassName可以反编译一个.class文件。

4. 锁住对象
早期版本的Java使用synchronized关键词,JDK5以后引入了ReentrantLock类。
使用ReentrantLock类保护代码块的基本轮廓:
myLock.lock(); // a ReentrantLock object
try
{
   critical section
}
finally
{
   myLock.unlock(); // make surethe lock is unlocked even if an exception is thrown
}
这样第一个线程调用lock方法锁住myLock后,第二个线程调用lock方法就会被block,并且得等到第一个线程调用myLock.unlock()后才能继续。
ReentrantLock类允许被多次锁定,它记录了呼叫的嵌套形式。大致是这个意思,原文是
The lock is called reentrant because a thread can repeatedlyacquire a lock that it already owns. The lock keeps a hold count that keeps track of the nestedcalls to the lockunlock forevery call to lock in order torelinquish the lock. Because of this feature, code that isprotected by a lock can call another method that uses the samelocks. method. Thethread has to call
For example, the TRansfer method calls the getTotalBalance method, which also locks thebankLock object, which now hasa hold count of 2. When the getTotalBalancetransfer method exits, the hold count is 0,and the thread relinquishes the lock. method exits, the hold countis back to 1. When the
In general, you will want to protect blocks ofcode that require multiple operations to update or inspect a datastructure. You are then assured that these operations run tocompletion before another thread can use the same object.
5. Condition Objects
ConditonObjects用来管理得了访问权,却实际并不能做有用功的线程。
以银行帐户转帐为例,转帐时要确定转出源的资金数不少于要转出的金额。
首先不能这样简单的写代码:
if (bank.getBalance(from) >= amount)
   bank.transfer(from, to,amount);
这种代码完全有可能在if语句判断完成后,transfer之前停滞,这样在调用transfer的时候,可能帐户当前的资金已经不是if语句判断那个时候的数目了。
也就是说,测试可行性和实际操作必须一起进行,之间不能有中断。
可以用一个lock把测试和操作绑定起来:
public void transfer(int from, int to, int amount)
{
   bankLock.lock();
   try
   {
     while (accounts[from] < amount)
     {
        // wait
        . . .
     }
     // transfer funds
     . . .
   }
   finally
   {
     bankLock.unlock();
   }
}
这样还是有问题,帐户资金不够移出时,会困在while块中等待资金拨入这个帐户,但由于bankLock已经被锁定,所以其他线程不能进行拨入操作,进入了死循环。这就是conditionobject产生的原因。
一个lock对象可以有一个或多个相关的conditionobject,可以通过newCondition方法获得一个条件对象,通常用实际条件命名每个条件对象,如
class Bank
{
   public Bank()
   {
     . . .
     sufficientFunds = bankLock.newCondition();
   }
   . . .
   private ConditionsufficientFunds;
}
当transfer方法发现当前资金不够时,调用
sufficientFunds.await();
这样当前线程就会停滞,并解除lock。
await方法调用后,线程进入对应Condition的等待区,直到另一个线程调用同一Condition的signalAll方法才会解除block状态,并等待再次被线程管理器激活。
如果一个线程调用了condition.await方法,却没有其他线程调用condition.signalAll,这个线程就进入了deadlock情况。如果所有其他的线程都进入了等待区,而最后一个线程也调用了condition.await,那么整个程序就挂起了。
因此最好的调用signalAll的时机是在每次对象的状态被改变,而这个改变有可能使得等待区的线程有进展的时候。如Bank中每次成功转帐之后。
另一个方法,signal,仅仅从等待区中随机选择一个进程并释放。
注意:线程只能在获得了lock权以后才能调用condition的await,signal, 和signalAll。
分享到:
评论

相关推荐

    并发编程示例,涉及到AtomicXXX、CountDownLatch、线程池等

    并发编程的一些小示例 1.等待通知的几种方式,包括Object的wait/notify,Condition的await/signal 2. CountDownLatch,统一控制多线程开始和结束 3.原子操作,AtomicXXX 4.线程池

    基础技术部牛路《Java多线程入阶分享》纯干货

    3.阻塞队列:put和take、offer和poll、drainTo 4.线程间通信:lock、condition、wait、notify、notifyAll 5.Lock-free:atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList 6.关于锁的经验介绍 7.并发流程...

    阿里Java并发程序设计教程

    3、阻塞队列 : put和take、offer和poll、drainTo 4、线程间的协调手段:lock、condition、wait、notify、notifyAll ☆ ☆ ☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList ☆ ☆ ☆ 6、...

    Java并发程序设计教程

    3、阻塞队列: put和take、offer和poll、drainTo 4、线程间的协调手段:lock、condition、wait、notify、notifyAll☆☆☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList☆☆☆ 6、关于锁...

    Java编程并发程序设计

    3、阻塞队列: put和take、offer和poll、drainTo 4、线程间的协调手段:lock、condition、wait、notify、notifyAll☆☆☆ 5、Lock-free: atomic、concurrentMap.putIfAbsent、CopyOnWriteArrayList☆☆☆ 6、关于锁...

    【2018最新最详细】并发多线程教程

    3.java内存模型以及happens-before规则 4.彻底理解synchronized 5.彻底理解volatile 6.你以为你真的了解final吗? 7.三大性质总结:原子性、可见性以及有序性 8.初识Lock与AbstractQueuedSynchronizer(AQS) 9.深入...

    并发编程笔记20190526.docx

    3、了解Condition的实现 42 4、 锁的可重入 44 第三章 并发容器ConcurrentHashMap 46 一、JDK1.7中原理和实现 47 1、分段锁机制 47 2、ConcurrentHashMap中的数据结构 47 3、ConcurrentHashMap初始化 48 4、...

    Java并发编程相关技术使用案例

    1、本资源包含并发编程基础知识的使用案例,包括:线程创建、Synchronized和Reentrantlock锁的使用、线程安全问题演示、Condition的应用、CountDownLatch的应用、Cyclicbarrier的应用、Semaphore的应用、线程池的...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段33讲、ThreadGroup API介绍之一.mp4 │ 高并发编程第一阶段34讲、ThreadGroup API介绍之二.mp4 │ 高并发编程第一阶段35讲、线程池原理与自定义线程池.mp4 │ 高并发编程第一阶段36讲、...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段33讲、ThreadGroup API介绍之一.mp4 │ 高并发编程第一阶段34讲、ThreadGroup API介绍之二.mp4 │ 高并发编程第一阶段35讲、线程池原理与自定义线程池.mp4 │ 高并发编程第一阶段36讲、...

    Java并发编程学习笔记

    3、ThreadLocal 的底层实现与使用 4、ReentrantLock底层实现和如何使用 5、Condition源码分析 6、ReentrantReadWriteLock底层实现原理 7、并发工具类CountDownLatch 、CyclicBarrier和Semaphore底层实现原理 8、...

    java并发编程-AQS和JUC实战

    java并发包详解,condition重入锁;Semaphore信号量;ReadWriteLock读写锁;CountDownLatch计时器;CyclicBarrier循环栅栏; 重⼊锁可以完全替代synchronized关键字。在JDK5.0的早期版本中,重⼊锁的性能远远好于 ...

    javaforkjoin源码-gitbook-BAT-interview:本文综合自己在一线互联网工作感悟,经验。记录开源框架的源码解读,数据

    [CountDownLatch] [CyclicBarrier] [Semaphore] [Exchanger] Atomic包 并发集合 [BlockQueue] [ArrayBlockingQueue] [ConcurrentLinkedQueue] [PriorityBlockingQueue] [DelayQueue] 并发安全集合 [HashMap, ...

    尚硅谷Java视频_JUC 视频教程

    尚硅谷_JUC线程高级_原子变量与 CAS 算法 ·3. 尚硅谷_JUC线程高级_模拟 CAS 算法 ·4. 尚硅谷_JUC线程高级_同步容器类ConcurrentHashMap ·5. 尚硅谷_JUC线程高级_CountDownLatch 闭锁 ·6. 实现 Callable 接口 ·...

    Java并发编程原理与实战

    使用Condition重写waitnotify案例并实现一个有界队列.mp4 深入解析Condition源码.mp4 实战:简易数据连接池.mp4 线程之间通信之join应用与实现原理剖析.mp4 ThreadLocal 使用及实现原理.mp4 并发工具类...

    java8源码-java8-source:java8

    java8 源码 java8源码+注释 AbstractQueuedSynchronizer ReentrantLock Condition CountDownLatch Semaphore

    这就是标题—— JUC.pdf

    Condition 定制化通信 多线程锁 并发下的集合类 List Set Map Callable接口 线程创建的方式 callable / runnable FutureTask JUC常用辅助类 CountDownLatch (减少计数器) CyclicBarrier(加法计数器) Semaphore...

    JDK_seaswalker.tar.gz

    Condition CountDownLatch CyclicBarrier ReadWriteLock ReentrantLock Socket UDP IO FileChannel Buffer URLConnection NIO Process HashMap LinkedHashMap TreeMap ConcurrentHashMap ...

    juc-demo:JUC包下常用工具练习Demo

    juc-demo JUC包下常用工具练习Demo 内容: 1、Semaphore 2、CountDownLatch 3、CyclicBarrier 4、ReentrantLock + Condition实现阻塞队列 Created by @minghui.y.

Global site tag (gtag.js) - Google Analytics