目录
ReentrantLock与 synchronized的区别
JUC全称java.util.concurrent,这个包里的内容主要就是跟多线程有关的组件。
Callable接口
Callable也是一种创建线程的方式,适合于想让某个线程执行一个逻辑,并返回结果的时候,相比之下,Runable不关注结果
- Callable<返回结果的类型>
- call()是Callable的核心方法,与Runable中的run()一样
完整的示例:
- FutureTask用来保存Callable的返回结果
ReentrantLock
ReentrantLock也是一个可重入锁,使用效果和synchronized是类似的;
优势:
- ReentrantLock在加锁的时候,有两种方式:lock,tryLock,提供更多的操作空间
- ReentrantLock提供了公平锁的实现,默认情况下是非公平锁
- ReentrantLock提供了更强大的等待通知机制,搭配了Condition类,实现等待通知
用法
- lock():加锁,如果获取不到锁就死等
- trylock():超时时间,加锁,如果获取不到锁,等待一定的时间后,放弃加锁
- unlock():解锁
ReentrantLock与 synchronized的区别
- synchronized是一个关键字,是JVM内部实现的,ReentrantLock是标准库中的一个类,是在JVM外实现的
- synchronized使用时不需要手动释放锁,ReentrantLock使用时需要手动释放锁
- synchronized在申请锁失败时,会死等,ReentrantLock可以通过trylock的方式等待一段时间后放弃
- synchronized是非公平锁,ReentrantLock默认是非公平锁,可以通过构造方法传入一个true开启公平锁模式
信号量Semaphore
信号量,就是一个计数器,描述“可用资源”的个数
- 申请一个资源,让计数器-1(P操作)
- 释放一个资源,让计数器+1(V操作)
锁本质上就属于一种特殊的信号量,可以看成可用资源为1的信号量,二元信号量(只有加锁和解锁操作)
CountDownLatch
适用于多个线程完成一系列任务的时候,用来衡量任务的进度是否完成,比如需要把一个大的任务,拆分成多个小的任务,让这些任务并发的去执行,就可以使用CountDownLatch来判定说当前的这些任务是否都完成了。
CountDownLatch的两个主要方法
- await,调用的时候会阻塞,就会等待其他的线程完成任务,所有的线程完成了任务之后,此时这个await才会继续往下走
- countDown,通知CountDownLatch,我当前这个子任务已经完成了