1.多线程常用用具类
-
ReentrantLock : 进行加锁解锁,实现数据同步
-
CountDownLatch : 设置一个数据,当在线程里面调用指定数据countDown方法后,放行指定线程
- 原理:
- new CountDownLatch(3):设置state变量数值为3;
- await():通过tryAcquireShared方法判断state数值是否为0;为0的话直接返回,如果不为0则通过循环CAS的方法调用tryAcquireShared判断是否为0,不为0的话则将线程添加到阻塞队列里面,通过locksupport.park()进行线程阻塞,等待唤醒。
- countDown():调用countdown()方法之后,判断state是否为0,不为0 则进行CAS减一操作,如果减一之后state值变为0,则唤醒阻塞队列里面所有阻塞的线程(从头到尾进行唤醒)
- node节店使用的是共享模式,共享模式特点是唤醒线程时会进行唤醒传递;即唤醒头结点之后接着唤醒下一个结点直到重新阻塞为止。
- 原理:
-
Semaphore : 信号量,同一时刻只能有指定线程同时进行;一般用于限流
- 原理:
- new Semaphore(4):设置state变量数值为4。
- semaphore.acquire():会对state值进行减一操作,如果操作之后state值为负数则调用aqs的doAcquireSharedInterruptibly(arg);方法进行线程阻塞挂起。
- semaphore.release(): 会对state值进行加一操作,加一成功之后调用aqs的doReleaseShared();方法进行线程的唤醒操作
- node节店使用的是共享模式,共享模式特点是唤醒线程时会进行唤醒传递;即唤醒头结点之后接着唤醒下一个结点直到重新阻塞为止;优点:释放资源的时候可能同时释放多个资源,这样就可以传递解锁,提高性能。
-
CyclicBarrier : 等指定个数了线程同时到达之后放行,可循环使用
- 原理:
- new CyclicBarrier(4,new Runnable(){}):定义需要等待的线程数,以及达到条件之后运行的任务
- cyclicBarrier.await(): 使用ReentrantLock进行同步保证,使用Condition进行等待唤醒;首先判断–count值是否为0,不为0则阻塞当前调用线程;为0则唤醒所有等待线程。
- 可以循环使用是因为里面维护了两个变量 parties和count,初始值都是构造方法传入数值;调用await方法时会对count进行减一操作;当–count为0时会将所有阻塞线程进行唤醒,同时将parties的值赋值给count保证工具可以重复使用。
- 原理:
-
Exchanger : 交换器,两个线程间交换数据使用,使用exchange方法进行交换数据
2.CountDownLatch和CyclicBarrier区别
- 含义不同:CountDownLatch是等若干个线程执行之后,被阻塞线程才可以执行;CyclicBarrier是等若干个线程到齐之后才可以同时执行
- CyclicBarrier可以循环使用,CountDownLatch不可以
- CountDownLatch在同一个线程里面调用多次,会对CountDownLatch的state减多次,CyclicBarrier必须等到指定个数线程同时到达才可以执行,用一个线程调用多次await方法没用。
3.queue常用方法总结
- add 往队列添加数据,越界时抛出异常
- offer 往队列添加数据,越界时返回添加失败
- remove 从对头获取数据,同时删除数据;队列为空时抛出异常
- poll 从对头获取数据,同时删除数据;队列为空时返回null
- element 从对头获取数据,不删除数据;队列为空时抛出异常
- peek 从对头获取数据,不删除数据;队列为空时返回null
- put 添加数据,越界时会阻塞等待有空间添加数据
- take 获取数据,为空时阻塞队列等待有数据
- transfer 传递数据,回阻塞线程直到数据被消费者消费为止
4.常用阻塞队列
- ArrayBlockingQueue : 数组阻塞队列。
- SynchronousQueue : 同步队列,队列不存数据,单纯用于数据交换。
- TransferQueue : 交换队列,可以存放数据;同时可以使用transfer实现线程间数据交换,类似SynchronousQueue功能;使用transfer数据不会放入队列里面,线程阻塞直到数据被获取。
- DelayQueue : 延迟队列,存放数据需要实现Delayed接口;队列里面数据可以按照时间进行排序。
- PriorityQueue: 可以对里面数据进行排序;优先级队列,队列存储对象需要实现Comparable接口,具有比较功能
- Deque:双向队列,增加了队尾,对头添加,移除的方法