• LongAdder,CyclicBarrier,MarriagePhaser,Semaphore


    效率

    线程数特别多的时候

    Longadder > Atomic > synchroinzed

    Longadder内部使用了分段锁

    Longadder是LongAccumulator的一种特殊形式

    ReentrantLock,synchronized对比

    cas vs sync

    trylock

    lockinterupptibly

    公平锁和非公平锁的切换

    • 如果一个线程组里,能保证每个线程都能拿到锁,那么这个锁就是公平锁
    • 相反,如果保证不了每个线程都能拿到锁,也就是存在有线程饿死,那么这个锁就是非公平锁
    在公平的锁中,如果有另一个线程持有锁或者有其他线程在等待队列中等待这个所,那么新发出的请求的线程将被放入到队列中
    而非公平锁上,只有当锁被某个线程持有时,新发出请求的线程才会被放入队列中(此时和公平锁是一样的)
    所以,它们的差别在于非公平锁会有更多的机会去抢占锁

    CyclicBarrier

    允许一组线程全部等待彼此达到共同屏障点的同步辅助。

    循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此

     屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用

    CyclicBarrier支持一个可选的Runnable命令,每个屏障点运行一次,在派对中的最后一个线程到达之后,但在任何线程释放之前

    在任何一方继续进行之前,此屏障操作对更新共享状态很有用

    实现原理

    在CyclicBarrier的内部定义了一个Lock对象,每当一个线程调用await方法时,将拦截的线程数减1,然后判断剩余拦截数是否为初始值parties

    如果不是,进入Lock对象的条件队列等待。

    如果是,执行barrierAction对象的Runnable方法,然后将锁的条件队列中的所有线程放入锁等待队列中,这些线程会依次的获取锁、释放锁

    构造方法 

    CyclicBarrier(int parties)

    创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待它时,它将跳闸,并且当屏障跳闸时不执行预定义的动作

    CyclicBarrier(int parties, Runnable barrierAction)

    创建一个新的 CyclicBarrier ,当给定数量的线程(线程)等待时,它将跳闸,当屏障跳闸时执行给定的屏障动作,由最后一个进入屏障的线程执行

    方法

    • int await() 等待所有 parties已经在这个障碍上调用了 await
    • int await(long timeout, TimeUnit unit) 等待所有 parties已经在此屏障上调用 await ,或指定的等待时间过去
    • int getNumberWaiting() 返回目前正在等待障碍的各方的数量
    • int getParties() 返回旅行这个障碍所需的parties数量
    • boolean isBroken() 查询这个障碍是否处于破碎状态
    • void reset() 将屏障重置为初始状态

    测试

    CountDownLatch和CyclicBarrier的比较

    • CountDownLatch是线程组之间的等待,即一个(或多个)线程等待N个线程完成某件事情之后再执行
    • CyclicBarrier则是线程组内的等待,即每个线程相互等待,即N个线程都被拦截之后,然后依次执行
    • CountDownLatch是减计数方式,而CyclicBarrier是加计数方式
    • CountDownLatch计数为0无法重置,而CyclicBarrier计数达到初始值,则可以重置
    • CountDownLatch不可以复用,而CyclicBarrier可以复用

    CyclicBarriar限流

    复杂操作

    • 数据库
    • 网络
    • 文件

    并发执行,不同的线程执行不同的操作

    MarriagePhaser(不重要)

    phase 是阶段的意思

    Phaser是按照不同阶段执行线程的,就像是结合了CountDownLatch和CyclicBarrier,它本身维护着一个叫 phase 的成员变量代表当前执行的阶段

    这是一个结婚的场景,自定义一个MarriagePhaser 继承 Phaser 重写Phaser的onAdvance方法定义了4个阶段(进入下一个阶段时该方法被自动调用)

    arrive,eat,leave,hug,所有人都能执行前三个方法,hug只能由新郎新娘执行

    读写锁,ReadWriteLock

    共享锁 + 排他锁,写锁排他,读锁共享

    ReentrantReadWriteLock有如下特性

    非公平模式(默认)

    当以非公平初始化时,读锁和写锁的获取的顺序是不确定的

    非公平锁主张竞争获取,可能会延缓一个或多个读或写线程,但是会比公平锁有更高的吞吐量

    公平模式

    当以公平模式初始化时,线程将会以队列的顺序获取锁

    当当前线程释放锁后,等待时间最长的写锁线程就会被分配写锁;或者有一组读线程组等待时间比写线程长,那么这组读线程组将会被分配读锁
    当有写线程持有写锁或者有等待的写线程时,一个尝试获取公平的读锁(非重入)的线程就会阻塞

    这个线程直到等待时间最长的写锁获得锁后并释放掉锁后才能获取到读锁

    可重入

    允许读锁可写锁可重入。写锁可以获得读锁,读锁不能获得写锁

    锁降级

    允许写锁降低为读锁

    中断锁的获取

    在读锁和写锁的获取过程中支持中断

    支持Condition

    写锁提供Condition实现监控

    提供确定锁是否被持有等辅助方法

    Semaphore(信号量)

    acquire,获得许可

    release,释放

    限流

    Exchanger

    交换数据,两两交换,交换结束后,两线程继续向下执行

    游戏中两人交换装备

    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    23.java方法的深入
    MapReduce:详解Shuffle过程
    Hadoop1.x与Hadoop2的区别
    进程控制的一些api
    程序的静态链接,动态链接和装载
    用户级线程和内核级线程的区别
    从Hadoop框架与MapReduce模式中谈海量数据处理(含淘宝技术架构) (转)
    海量处理面试题
    面试中的二叉树题目
    linux 进程间消息队列通讯
  • 原文地址:https://www.cnblogs.com/YC-L/p/14432962.html
Copyright © 2020-2023  润新知