决战圣地玛丽乔亚Day31---读写锁/countdown/LockSupport

读写锁有哪些?

juc的locks包的readwriteLock接口和ReentrantReadWriteLock类来实现。

 ReentrantReadWriteLock:

最常见的读写锁,读共享,写互斥。可重入。

锁降级:获取写锁,获取读锁,释放写锁。

需要严格按照这三步来做,获取读锁是为了让其他线程获取写锁时被阻塞,不会修改数据造成不可见的情况。

StampedLock:

JAVA8在ReentrantReadWriteLock基础上进行优化。读锁、写锁、乐观读锁三种模式。

乐观读:其他线程尝试获取写锁时不会被阻塞,这其实是对读锁的优化,所以,在获取乐观读锁后,还需要对结果进行校验(通过版本号)。

对短的只读代码段,使用乐观模式通常可以减少争用并提高吞吐量。

所有获取锁的方法,都返回一个邮戳(Stamp), stamp为零表示获取失败,其余都表示成功;

所有释放锁的方法,都需要一个邮戳(Stamp),这个Stamp必须是和成功获取锁时得到的Stamp一致;

StampedLock是不可重入的,危险(如果一个线程已经持有了写锁,再去获取写锁的话就会造成死锁)

 通过版本号+CAS的乐观锁模式来保证数据尽量的一致性。建议高并发还是用ReentrantReadWriteLock的悲观读模式。

 

countdownLatch:计数器阻塞唤醒
主要构成是一个计数器,一个await()方法,一个countDown方法。

主线程new一个CountdownLatch方法,指定初始化的数量。

子线程每次执行完调用countDown方法把计数器-1

如果计数器为0,调用await方法会返回继续执行下面的任务,否则会被阻塞。  注意给一个超时限制之类的,不要造成一直阻塞的状况。

 

cyclebarrier

CyclicBarrier是Java并发包中的一个同步工具,它可以让一组线程在达到某个屏障点之前相互等待,然后一起执行下一步操作。具体来说,CyclicBarrier的作用是将一组线程拦截在屏障前面,直到所有线程都到达屏障,才会继续执行后续操作。CyclicBarrier可以循环使用,即当所有线程都通过屏障后,屏障可以重置,再次等待下一轮的线程到达。

CyclicBarrier可以用于需要多个线程协作完成某个任务的场景,比如计算某个大型任务的多个子任务的结果,然后将这些结果进行合并,或者在一个并行计算框架中,将多个任务的结果汇总到一个共享数据结构中。

CyclicBarrier的一个重要特性是,它可以指定一个Runnable对象,在所有线程都通过屏障后,这个Runnable对象会被自动执行。这样可以方便地进行后续的操作,比如数据合并、结果处理等。

 

 

 

LockSupport是什么,阻塞的细节

park  & unpark和 wait &notify有什么区别?

1.park不需要获取对象的锁,直接调用加上线程参数。park中断不会抛出异常,需要自己写中断逻辑。

例如:

if (Thread.currentThread().isInterrupted()) {
        System.out.println("被中断了");
}
System.out.println("继续执行");

 2.park,unpark不会出现死锁情况。wait、notify可能会。

park和unpark会对每个线程维护一个boolean许可值。

在上面的文字中,我使用了阻塞和唤醒,是为了和wait/notify做对比。

其实park/unpark的设计原理核心是“许可”。park是等待一个许可。unpark是为某线程提供一个许可。如果某线程A调用park,那么除非另外一个线程调用unpark(A)给A一个许可,否则线程A将阻塞在park操作上。

 

也就是说,unpark可以先于park执行。调用unpark时,会给许可标记为true,下次调用park的时候会立即返回并清除许可标记,不会像wait/notify那样被阻塞。所以使用park和unpark更加灵活。

阻塞和唤醒的细节:

  1. 当线程调用park()方法时,如果许可证标记为1,则该方法会立即返回,并将许可证标记清除为0。否则,该线程会被阻塞,并等待许可证标记为1。

  2. 当线程调用unpark()方法时,如果该线程没有被阻塞,则该方法会将许可证标记设置为1,并立即返回。否则,该线程会被唤醒,许可证标记被清除为0,然后该方法返回。

需要注意的是,unpark()方法可以在park()方法之前调用,这是因为许可证标记不会丢失,会一直保持有效状态,直到下次调用park()方法时被消费掉。另外,如果线程在调用park()方法时被中断,它也会立即返回,并将中断标记设置为true。

posted @   NobodyHero  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
历史上的今天:
2017-03-12 常用类---正则表达式
点击右上角即可分享
微信分享提示