java锁机制

本文介绍了Java中几种常见锁的特点。可重入锁如ReentrantLock和synchronized,线程无需重复申请锁;可中断锁如Lock,线程等待时可中断;公平锁按请求顺序获取锁;读写锁将访问资源分为读锁和写锁;自旋锁是非阻塞锁,但存在占CPU时间和死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、可重入锁

      对于可重入的理解:

      class MyClass {
                public synchronized void method1() {
                          method2();
                }
                public synchronized void method2() {
                }
      }

      上述代码中,假如线程A执行到了method1,此时线程A获取了这个对象的锁,method1会调用同样由synchronized修饰的method2,此时线程不必重新申请锁,可以直接执行方法method2。如果synchronized不具备可重入性,此时线程A需要重新申请锁。由于线程A已经持有了该对象的锁,而又在申请获取该对象的锁,这样就会线程A一直等待永远不会获取到的锁。

       ReentrantLock和synchronized锁都是可重入锁。

2、可中断锁

       线程B等待线程A执行锁中的代码,如果线程B可以中断等待线程A去执行其他代码,这种就是可中断锁。

       Lock是可中断锁,synchronized不是可中断锁。

3、公平锁

       尽量以请求锁的顺序来获取锁,最先请求的的线程获得锁,就是公平锁。

       无法保证锁的获取是按照申请的顺序,就是非公平锁。这样会导致某一个或某几个线程永远获取不到锁。

       synchronized是非公平锁,ReentrantLock和ReentrantReadWriteLock默认非公平锁,但可以设置为公平锁。ReentrantReadWriteLock并未实现Lock接口,它实现的是ReadWriteLock接口。

4、读写锁

        读写锁将对一个资源的访问分成了两个锁,读锁和写锁。ReadWriteLock就是读写锁,它是一个接口,ReentrantReadWriteLock实现了这个接口。

        可以通过readLock()获取读锁,通过writeLock()获取写锁。

5、自旋锁

        普通锁:线程A在获得普通锁后,如果再有线程B试图获取锁,那么这个线程B将会挂起(阻塞)

        自旋锁:线程A在获得普通锁后,线程B可以不放弃CPU时间片,而是在“原地”忙等,直到锁的持有者释放了该锁,是一种非阻塞锁。

         有两个问题:

                 1.过多占据CPU时间
                 2.死锁问题:有一个线程连续两次试图获得自旋锁(比如在递归程序中),第一次这个线程获得了该锁,当第二次试图加锁的时候,检测到锁已被占用(其实是被自己占用),那么这时,线程会一直等待自己释放该锁,而不能继续执行,这样就引起了死锁。因此递归程序使用自旋锁应该遵循以下原则:递归程序决不能在持有自旋锁时调用它自己,也决不能在递归调用时试图获得相同的自旋锁。

         摘抄和简化自https://blog.youkuaiyun.com/sunp823/article/details/49886051https://www.cnblogs.com/aspirant/p/6930436.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值