首页 > 编程语言 >Java面试-基础篇(一)6

Java面试-基础篇(一)6

时间:2023-03-24 23:00:49浏览次数:34  
标签:Java synchronized Lock ReentrantLock 基础 面试 线程 公平 lock

synchronized与ReentrantLock的区别

说到synchronized与ReentrantLock,我们都知道,他们是java并发编程很重要的技术。他们可以帮助我们保证编程过程中数据的正确性,也就是我们常说的线程安全。

线程安全通常是多个线程在执行一段代码时采用锁机制实现的。

介绍锁机制前,先了解一下锁的分类。

从设计理念来分,有悲观锁和乐观锁。

悲观锁:认为每次拿数据时,别的线程都抢占修改,所以读写时,将数据进行锁定。

乐观锁:认为每次拿数据时,别的线程并不会抢占修改,所以拿数据处理时不上锁,处理完毕后,将处理完的数据写回内存时,进行判断,如果与预期一致则进行更新,不一致则更新失败。此处使用的时CAS(compare and swap)机制。

从锁的现象可分为公平锁和非公平锁

公平锁:某一线程释放资源后,按顺序唤醒下一个等待的线程,他们之间是排队的,有序的,每个线程都能获得执行的机会。在公平锁的情况下,它的好处是资源平均分配不会有线程饿死的情况。缺点是它的按顺序唤醒线程的开销过大,执行性能不高。

非公平锁:线程执行完毕后,接下来执行的线程进行抢占资源,谁抢到了,谁就执行,没有抢到的就滚去排队。他们之间是不排队的,无序的。每个线程获取执行的机会不相等,所以叫非公平锁。非公平锁的好处是执行效率高,谁抢到就谁用,不会按顺序唤醒线程,缺点是资源分配随机性强,可能会出现线程饿死的情况。

从锁的状态来分可分为偏向锁和重量级锁。

这3种锁其实是有关联的。偏向锁是某一线程持有锁时,等他用完锁以后再想用时,它在其他的线程中是优先级最高的,它可以一直持有锁。

而某一线程持有偏向锁,当其他线程来访问时获取不到锁,就会一直自旋,等待获取锁。此时偏向锁升级为了轻量级锁。

当线程一直获取不到锁,自旋一定的次数,线程就会阻塞。该锁就会升级为重量级锁。升级为重量级锁以后,当有线程再过来访问时,都会被阻塞,直到获取锁。

synchronized与ReentrantLock默认都是非公平锁,在java6以前,synchronized是重量级锁,所以那时候一般没人用。后来优化后好多了。

ReentrantLock可以通过修改配置修改为公平锁,但是synchronized就一直是非公平锁。

当使用 new ReentrantLock(true) 时,可以创建公平锁,如下源码所示:

 

 

 synchronized依赖于JVM,而ReentrantLock依赖于API,它是一个类,底层其实调用Lock接口,在此接口上做了实现,ReentrantLock需要显式的加锁和解锁。

public class ReentrantLock implements Lock, java.io.Serializable {
private final Sync sync;

/**
* Base of synchronization control for this lock. Subclassed
* into fair and nonfair versions below. Uses AQS state to
* represent the number of holds on the lock.
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;

/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();
}

  ReentrantLock相比较synchronized而言增加了一些功能。

  1. 等待可中断。ReentrantLock提供了一种能够钟断等待锁的线程机制,能够使等待的线程,先中断等待去做别的事情,使用Lock LockInterruptibly()实现
  2. 可实现公平锁。通过ReentrantLock类的ReentrantLock(boolean fair)构造方法实现
  3. 可选择性通知,唤醒线程(锁可以绑定多个条件)。该功能需要借助condition接口于new Condition()方法。而synchronized需要使用wait(),notify(),notifyAll()方法实现等待/通知的机制

 

标签:Java,synchronized,Lock,ReentrantLock,基础,面试,线程,公平,lock
From: https://www.cnblogs.com/stying/p/17253571.html

相关文章

  • 编写一个方法,计算给定两个数组之和---Java
    要求返回的数组是两个惨呼数组对应元素之和,不对应的元素直接赋给相应的位置packagepractice.people.apple;/**//编写一个计算给定的两数组之和**/publicclassS......
  • java学习日记20230324-final关键字
    final可以修饰类,方法,属性和局部变量当不希望类被继承时,用final修饰类当不希望父类某个方法被子类重写时,使用final当不希望某个属性值被修改时当不希望某个局部变量被......
  • JavaScript数值计算时精度问题处理
    js精度问题当使用JavaScript进行数值计算时,会面临一些精度问题,这些问题可能会导致不正确的结果。以下是一些常见的奇奇怪怪的js数据精度问题:1.浮点数精度问题在JS......
  • C语言基础知识
    1、变量类型   字符型--char--所占字节(1)   整型--int--所占字节(4)   短整型--short--所占字节(2)   长整型--long--所占字节(4)   更长的整形--longlo......
  • 面试
    C/C++: 1.指针和引用的区别2.C++的特性3.堆和栈的区别4.静态编译和动态编译5.vector和list的区别6.析构函数虚析构纯虚析构函数的区别和作用   操作系统:......
  • 计算机基础
    计算机基础逻辑门逻辑门是一种常见的元器件,能够执行一种或多种逻辑运算。常见的逻辑门有:与门(ANDgate)、或门(ORgate)、非门(NOTgate)、异或门(XORgate)等。与或非是计算机......
  • Mq面试题
    1、MQ有哪些使用场景?(高频)异步处理:用户注册后,发送注册邮件和注册短信。用户注册完成后,提交任务到MQ,发送模块并行获取MQ中的任务。系统解耦:比如用注册完成,再加一个发......
  • 通信基础知识-名词解释
    AWGN:加性高斯白噪声(AWGN)是一个数学模型,用于仿真发射机和接收机之间的信道。这个模型是线性增加的宽带噪声,具有恒定的频谱密度和高斯分布的幅度。AWGN不适用于衰落、互......
  • Java生产者消费者
    生产者消费者问题简介生产者消费者模式并不是GOF提出的23种设计模式之一,23种设计模式都是建立在面向对象的基础之上的,但其实面向过程的编程中也有很多高效的编程模式,生产......
  • 【THM】Pentesting Fundamentals(渗透测试基础介绍)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/pentestingfundamentals本文相关内容:了解渗透测试背后的重要道德规范和方法论。什么是渗透测试?在学习道......