决战圣地玛丽乔亚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 ¬ify有什么区别?
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更加灵活。
阻塞和唤醒的细节:
-
当线程调用park()方法时,如果许可证标记为1,则该方法会立即返回,并将许可证标记清除为0。否则,该线程会被阻塞,并等待许可证标记为1。
-
当线程调用unpark()方法时,如果该线程没有被阻塞,则该方法会将许可证标记设置为1,并立即返回。否则,该线程会被唤醒,许可证标记被清除为0,然后该方法返回。
需要注意的是,unpark()方法可以在park()方法之前调用,这是因为许可证标记不会丢失,会一直保持有效状态,直到下次调用park()方法时被消费掉。另外,如果线程在调用park()方法时被中断,它也会立即返回,并将中断标记设置为true。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
2017-03-12 常用类---正则表达式