java中锁的分类

一、锁的整体分类

在java中锁被分成了4类,即:

      1、可重入锁、不可重入锁

      2、乐观锁、悲观锁

      3、公平锁、非公平锁

      4、共享锁、互斥锁

二、可重入锁、不可重入锁

      1、可重入锁:当线程A已经拿到了锁S,当线程A再次场次获取锁S,线程A是可以获取

                             到锁S的;可重入锁拿到了几次,线程释放锁时就要释放同样次数的锁。

                            java中的synchronized、ReentrantLock、ReentrantReadWriteLock都是

                            可重入锁。

      2、不可重入锁:当线程A已经拿到了锁S,当线程A再次场次获取锁S,线程A是不可以获取

                                 到锁S的,因为锁S已经被占用;如 线程池 ThreadPoolExecutor 中的内部

                                 类 Worker 就是一个不可重入锁,其获取锁的代码如下图所示:

                                

三、乐观锁、悲观锁

       1、乐观锁

             获取不到锁资源时,可以让CPU调度再次尝试获取锁资源(可以看成“自旋”,)

             java中提供的CAS操作就是一种乐观锁的实现方式,他不涉及线程的挂起操作,

             

       2、悲观锁

             当获取不到锁资源时,会将当前线程挂起(即将当前线程设置为 BLOCKED

             或 WAITING 状态);线程的挂起或涉及用户态和内核态之间的切换,而这种切换

             是非常消耗CPU资源的,所以应该尽量避免用户态与内核态之间的切换。

             java中的synchronized、ReentrantLock、ReentrantReadWriteLock都是悲观锁

四、公平锁、非公平锁

       1、公平锁

             当线程A、B同时去竞争锁资源T,若A成功拿到了锁T,线程B没有拿到锁T,线程B去

             排队等待A释放锁资源;此时线程C进来了,锁T被A持有,同时线程B在排队,此时线程

             C也需要去排队且C排到B后边。

       2、非公平锁

              当线程A、B同时去竞争锁资源T,若A成功拿到了锁T,线程B没有拿到锁T,线程B去

             排队等待A释放锁资源;此时线程C进来了,线程C先去尝试竞争一下锁资源,若C竞争

            到了锁T,则C持有锁资源,否则线程C需要去排队且C排到B后边。

            java中的synchronized 一定是非公平锁

            java中的ReentrantLock、ReentrantReadWriteLock 可以是公平锁,也可以是非公平锁。

五、共享锁、互斥锁

       1、共享锁

            同一时间点,可以有多个线程同时持有的锁称为共享锁

       2、互斥锁

            同一时间点,只有一个线程能持有的锁 称为互斥锁;

           java中的synchronized、ReentrantLock 是互斥锁

          java中的 ReentrantReadWriteLock有互斥锁也有共享锁,其中写锁是互斥锁,读锁是共享锁

<think>好的,我现在需要回答用户关于Java分类的问题。首先,我要回顾用户提供的引用内容,看看里面提到了哪些的类型和分类。 引用[1]提到非可重入,独占和共享。引用[2]和[3]主要讲ReentrantLock作为可重入的实现,还有公平和非公平的区别。引用[4]则提到synchronized关键字属于独占、悲观、可重入、非公平,还提到了作用范围的不同情况。综合这些信息,Java中的可以从多个维度分类,比如可重入性、公平性、的性质(如悲观/乐观)、独占/共享等。 接下来需要组织这些分类,确保每个类别都有明确的定义和例子。例如,按可重入性分为可重入和非可重入,但用户提到Java标准库中没有非可重入的实现,可能需要说明这一点。然后,按公平性分为公平和非公平,ReentrantLock支持这两种模式。独占和共享是另一组分类,像ReentrantLock是独占,而ReadWriteLock中的读是共享。另外,还有悲观和乐观,synchronized和ReentrantLock属于悲观,而StampedLock的乐观读属于乐观。 要注意引用中的例子,比如ReentrantLock的代码示例,以及synchronized的不同使用方式。需要将这些例子融入分类中,帮助用户理解。同时,用户可能对某些概念不太清楚,比如公平和非公平的区别,需要简单解释。 可能还需要检查是否有其他常见的类型没有被提到,比如自旋,但根据引用内容,可能不在讨论范围内,所以暂时不加入。最后,生成相关问题,确保问题覆盖分类的各个方面,帮助用户进一步学习。</think>### Java分类及类型解析 Java中的机制是实现多线程同步的核心工具,根据不同的特性和应用场景,可以分为以下几类: --- #### 一、**按可重入性分类** 1. **可重入(Reentrant Lock)** - **定义**:线程可以重复获取已持有的,避免死。 - **实现**: - `synchronized`关键字默认支持可重入性[^4]。 - `ReentrantLock`是显式的可重入实现[^2][^3]。 - **示例**: ```java public void outerMethod() { lock.lock(); // 第一次获取 try { innerMethod(); // 再次获取同一 } finally { lock.unlock(); } } ``` 2. **非可重入** - **定义**:同一线程不可重复获取已持有的。 - **现状**:Java标准库未提供现成实现,需自定义[^1]。 --- #### 二、**按公平性分类** 1. **公平** - **规则**:按线程请求顺序分配,避免饥饿。 - **实现**:`ReentrantLock(true)`[^2]。 2. **非公平** - **规则**:允许插队,提高吞吐量但可能引发饥饿。 - **实现**:`synchronized`和`ReentrantLock()`默认模式[^4][^2]。 --- #### 三、**按的性质分类** 1. **独占(互斥)** - **定义**:同一时间仅一个线程可持有。 - **示例**:`synchronized`、`ReentrantLock`[^4][^2]。 2. **共享** - **定义**:允许多个线程同时读,写时互斥。 - **实现**:`ReadWriteLock`中的读[^1]。 --- #### 四、**按的乐观性分类** 1. **悲观** - **假设**:认为并发冲突频繁,直接加。 - **示例**:`synchronized`、`ReentrantLock`[^4][^2]。 2. **乐观** - **假设**:冲突较少,通过版本号(如CAS)实现。 - **实现**:`StampedLock`的乐观读模式[^1]。 --- #### 五、**其他分类** 1. **自旋** - **特点**:线程通过循环尝试获取,避免上下文切换。 - **适用场景**:竞争低且持有时间短的情况。 2. **分段** - **设计**:将数据分段,每段独立加(如`ConcurrentHashMap`)。 --- ### 总结对比 | 分类维度 | 类型 | 特点/实现 | |----------------|---------------|-----------------------------------| | **可重入性** | 可重入 | `synchronized`, `ReentrantLock` | | | 非可重入 | 需自定义[^1] | | **公平性** | 公平 | `ReentrantLock(true)`[^2] | | | 非公平 | 默认模式 | | **性质** | 独占 | 互斥访问 | | | 共享 | 读共享,写互斥 | | **乐观性** | 悲观 | 直接加 | | | 乐观 | CAS或版本控制 | --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值