ReentrantLock
- 特点:
- 可重入
- 可中断:可对正在执行的线程进行中断
- 可限时:可以设置在多少时间单位内没有获取到资源则执行其他业务方法
- 公平锁:避免产生饥饿现象,但是性能会降低
- 重入锁实现:
- cas状态:判断当前锁是否被占用
- 等待队列:将所有在等待状态的线程都保存在队列中
- park():对进入队列的线程进行挂起,当拥有锁的线程释放完锁后,会调用unpark()启动队列的第一个线程进行资源访问。
- 说明:重入锁也可以称为递归锁,当外层方法获取到锁时,在锁内的代码段或时方法都会默认的获取到锁,那获取到锁的线程就和进入任何一个已经拥有锁的代码。
- 补充:synchroized关键字也是重入锁,但确是非公平锁,jdk1.5后对synchroized进行了优化,所以二者没有太多的差别。
Condition
- 概述
- 类似于Object.wait()和Object.notify()
- 与 ReentrantLock结合使用
Semaphore
- 概述:
- 共享锁
- 运行多个线程进入临界去,当只允许一个线程进入时就可以当作普通锁来使用
- 可以使用在某些不能支持太多请求的系统中,使用共享锁设置具体容量,超过容量的线程就进入等待状态
ReadWriteLock
- 增加并行度(读不加锁写枷锁)
- 当没有写的功能的情况下读线程是无等待的并发
- 读-读不互斥:读读之间不阻塞
- 读-写互斥:读阻塞写,写也会阻塞读
- 写-写互斥:写写阻塞。
CountDownLatch
- 倒数计时器:顾名思义,通过用户自定义一个线程数count,在执行线程时通过倒数计时器对count进行扣减,当count被扣减到0时就会触发倒数计时器在主线程中的等待方法进行放行。
- 举例:
public class Test{
static final CountDownLatch end=new CountDownLatch(10);
static final MyThread td=new MyThread();
public static void main(String[] args) {
ExecutorService exec=Executors.newFixedThreadPool(10);
for (int i = 0; i < 10 ; i++) {
exec.execute(td);
}
exec.shutdown();
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发射");
}
}
class MyThread implements Runnable{
public void run(){
try {
Thread.sleep(new Random().nextInt(10)*100);
System.out.println(Thread.currentThread().getName()+"进行了检查");
} catch (InterruptedException e) {
e.printStackTrace();
}
Test.end.countDown();
}
}
执行结果:
pool-1-thread-7进行了检查
pool-1-thread-4进行了检查
pool-1-thread-1进行了检查
pool-1-thread-8进行了检查
pool-1-thread-3进行了检查
pool-1-thread-10进行了检查
pool-1-thread-6进行了检查
pool-1-thread-2进行了检查
pool-1-thread-5进行了检查
pool-1-thread-9进行了检查
发射
CyclicBarrier
- 循环栅栏:类似于倒数计时器,但是cylicBarrier则是循环技术,也就是说这个计数器是可以反复使用的,比如:假设我们的计数器设置为10,那么等一批的10个线程执行完成后计数器就会归零,然后接着又筹齐下一批的10个线程,以此来不断对进入的线程进行拦截集合。
- 举例:
public class CyclicBarrierTest
{
static final CyclicBarrier barrier=new CyclicBarrier(10,new MyBarrierAction());
static final MyThread1 td=new MyThread1();
public static void main(String[] args) {
ExecutorService exec= Executors.newFixedThreadPool(10);
for (int i = 0; i < 10 ; i++) {
exec.execute(td);
}
exec.shutdown();
}
}
class MyBarrierAction implements Runnable{
public void run() {
System.out.println("都集合完毕了");
}
}
class MyThread1 implements Runnable{
public void run(){
try {
CyclicBarrierTest.barrier.await();
doWork();
CyclicBarrierTest.barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
private static void doWork() {
try {
Thread.sleep(new Random().nextInt(10)*100);
System.out.println("线程"+Thread.currentThread().getName()+"执行完毕!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
打印结果:
都集合完毕了
线程pool-1-thread-3执行完毕!
线程pool-1-thread-9执行完毕!
线程pool-1-thread-6执行完毕!
线程pool-1-thread-8执行完毕!
线程pool-1-thread-2执行完毕!
线程pool-1-thread-4执行完毕!
线程pool-1-thread-10执行完毕!
线程pool-1-thread-7执行完毕!
线程pool-1-thread-5执行完毕!
线程pool-1-thread-1执行完毕!
都集合完毕了