- package test;
- import java.util.concurrent.CyclicBarrier;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class Recipes_CyclicBarrier {public static CyclicBarrier barrier = new CyclicBarrier(10);
- public static void main(String[] args){
- ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);
- for(int i=1;i<=10;i++){
- executor.submit(new Thread(new Runner(i+"号选手")));
- }
- executor.shutdown();
- }
- }
- class Runner implements Runnable{
- private String name;
- public Runner(String name){
- this.name = name;
- }
- @Override
- public void run() {
- System.out.println(name + "准备好了");
- try {
- Recipes_CyclicBarrier.barrier.await(); // 此处就是公共屏障点, 所有线程到达之后, 会释放所有等待的线程
- } catch (Exception e) {
- }
- System.out.println(name + "起跑!");
- }
- }
- 2CountDownLatch
CountDownLatch 和 CyclicBarrier 有点类似, 但是还是有些区别的 CountDownLatch 也是一个同步辅助类, 它允许一个或者多个线程一直等待, 直到正在其他线程中执行的操作完成它是等待正在其他线程中执行的操作, 并不是线程之间相互等待 CountDownLatch 初始化时需要给定一个计数值, 每个线程执行完之后, 必须调用 countDown() 方法使计数值减 1, 直到计数值为 0, 此时等待的线程才会释放
来个示例:
- [java] view plain copy
- package test;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.CyclicBarrier;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class CountDownLatchDemo {
- public static CountDownLatch countDownLatch = new CountDownLatch(10);// 初始化计数值
- public static void main(String[] args){
- ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);
- for(int i=1;i<=10;i++){
- executor.submit(new Thread(new Runner1(i+"号选手")));
- }
- executor.shutdown();
- }
- }
- class Runner1 implements Runnable{
- private String name;
- public Runner1(String name){
- this.name = name;
- }
- @Override
- public void run() {
- System.out.println(name + "准备好了");
- CountDownLatchDemo.countDownLatch.countDown(); // 计数值减 1
- try {
- CountDownLatchDemo.countDownLatch.await();
- } catch (Exception e) {
- }
- System.out.println(name + "起跑!");
- }
- }
- 3CopyOnWriteArrayList & CopyOnWriteArraySet
CopyOnWriteArrayList & CopyOnWriteArraySet 是并发容器, 适合读多写少的场景, 如网站的黑白名单设置缺点是内存占用大, 数据一致性的问题, CopyOnWrite 容器只能保证数据最终的一致性, 不能保证数据实时一致性鉴于它的这些缺点, 可以使用 ConcurrentHashMap 容器
实现原理: 新增到容器的数据会放到一个新的容器中, 然后将原容器的引用指向新容器, 旧容器也会存在, 因此会有两个容器占用内存我们也可以用同样的方式实现自己的 CopyOnWriteMap
4ConcurrentHashMap
ConcurrentHashMap 同样是一个并发容器, 将同步粒度最小化
实现原理: ConcurrentHashMap 默认是由 16 个 Segment 组成, 每个 Segment 由多个 Hashtable 组成, 数据变更需要经过两次哈希算法, 第一次哈希定位到 Segment, 第二次哈希定位到 Segment 下的 Hashtable, 容器只会将单个 Segment 锁住, 然后操作 Segment 下的 Hashtable, 多个 Segment 之间不受影响如果需要扩容不是对 Segment 扩容而是对 Segment 下的 Hashtable 扩容虽然经过两次哈希算法会使效率降低, 但是比锁住整个容器效率要高得多
5BlockingQueue
BlockingQueue 只是一个接口, 它的实现类有 ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueSynchronousQueueDelayQueueLinkedBlockingDeque
ArrayBlockingQueue: 由数据支持的有界阻塞队列
LinkedBlockingQueue: 基于链接节点范围任意的阻塞队列
PriorityBlockingQueue: 无界阻塞队列
SynchronousQueue: 一种阻塞队列, 其中每个插入操作必须等待另一个线程的对应移除操作
DelayQueue:Delayed 元素的一个无界阻塞队列
LinkedBlockingDeque: 基于链接节点范围任意的双端阻塞队列, 可以在队列的两端添加移除元素
6Lock
Lock 分为公平锁和非公平锁, 默认是非公平锁实现类有 ReetrantLockReetrantReadWriteLock, 都依赖于 AbstractQueuedSynchronizer 抽象类 ReetrantLock 将所有 Lock 接口的操作都委派到 Sync 类上, Sync 有两个子类: NonFairSync 和 FaiSync, 通过其命名就能知道分别处理非公平锁和公平锁的 AbstractQueuedSynchronizer 把所有请求构成一个 CLH 队列, 这里是一个虚拟队列, 当有线程竞争锁时, 该线程会首先尝试是否能获取锁, 这种做法对于在队列中等待的线程来说是非公平的, 如果有线程正在 Running, 那么通过循环的 CAS 操作将此线程增加到队尾, 直至添加成功
7Atomic 包
Atomic 包下的类实现了原子操作, 有对基本类型如 intlongboolean 实现原子操作的类: AtomicIntegerAtomicLongAtomicBoolean, 如果需要对一个对象进行原子操作, 也有对对象引用进行原子操作的 AtomicReference 类, 还有对对象数组操作的原子类: AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray 原子操作核心思想是 CAS 操作, 然后调用底层操作系统指令来实现
来源: http://www.bubuko.com/infodetail-2517123.html