内容提要
• 通过wait,nofity管理并发
• 通过Condition实现线程间的通讯
• 通过Semaphore管理多线程的竞争
以生产者消费者问题观察wait和notify
• 一旦执行wait方法,会释放synchronized所关联的锁,进 入阻塞状态,无法再次主动地到可执行状态
• 这两个方法需要放置在synchronized的作用域里
• notifyAll会唤醒因wait而进入到阻塞状态的线程,但它们 没得到锁,因此会竞争锁,得到锁的继续执行,在它释放 锁后,其它线程会继续竞争,以此类推。
• 一旦执行notify方法,会通知因调用wait方法而等待锁的 线程,如有多个线程等待,则会任意挑选一个线程来唤醒
edu.csdn.net
以生产者消费者问题观察wait和notify
• 当仓库空,notify生产者线程,wait消费者线程
• 当仓库满,wait生产者线程,notify消费者线程
• 一旦执行notify方法,会通知因调用wait方法而等待锁的 线程,如有多个线程等待,则会任意挑选一个线程来唤醒
通过Condition实现线程间的通讯
• 通过Condition类,可以在不同的线程里创建多个阻塞队列。
• 当线程A调用Condition的await方法后,会释放相应的对 象锁,并且让自己进入阻塞状态,等待被其它线程唤醒
• 基于Object类的wait、notify和notifyAll的方法,只能建立一个阻 塞队列
• 线程B得到锁资源后,开始执行业务,完成后,能调用Condition 的signal方法,唤醒线程A,让线程A恢复执行
通过Semaphore管理多线程的竞争
• 用acquire方法申请资源,用release方法释放资源
• 多个线程需要竞争数量相对少的资源,比如100个线程需要连接到 同一个数据库上,但任何时刻,数据库最多只能提供10个连接
• 构造函数,public Semaphore(int permits,boolean fair),permits 参数表示初始化可用的资源数目,而fair表示是否是公平锁。
• Semaphore类是个计数信号量
总结
1. 了解了线程并发时需要解决的问题 2. 通过notify和wait管理并发 3. 通过Condition管理并发 4. 通过Semaphore管理多线程竞争资源
内容提要
• 同步计数器CountDownLatch的用法
• 线程通过Callable返回结果,通过Future获取结果
• 通过CompletableFuture管理多线程
同步计数器CountDownLatch的用法
• countDown()方法对计数器做减操作
• CountDownLatch有一个正数计数器
• 能保证以CountDownLatch所标记的前置任务都完成后, 主任务再执行
• 直到所有的计数器都归0(或中断或超时),await线程才 会继续,否则会一直阻塞
同步计数器CountDownLatch的范例
• 用future得到Callable的返回
• 通过Callable类对象得到返回结果
• 调用3个任务里全部得到结果后,再把结果一并组装成List, 用CountDowLatch来统计3个线程的完成情况
• 多个线程任务用线程池管理
• 通过await设置服务超时时间
Future的局限 vs 实际业务需求
• 实际上要合并多个线程计算结果
• 每个Future是独立的,多个Future间很难关联
• 需要合并多个线程的计算结果
• 多个线程并发,谁先返回就用谁的结果
CompletableFuture
• 通过applyToEither方法,使用先返回的结果
• 在supplyAsync方法里定义要执行的任务
• 基于jdk1.8里的lambad表达式
• 通过thenCombine方法整合多个线程的返回结果
• 通过thenAccept方法,消费之前线程的结果
面试时有备无患
• 找个业务点,套上CountDownLatch
• CompletableFuture,一般业务场景未必会用,但要会说
总结
1. 了解了通过CountDownLatch管理多线程协作的方法
2. 了解了通过Callable返回线程结果的方法
3. 掌握了用CompletableFuture类管理多线程间依赖的做法