1.谈谈synchronized与Lock锁的区别?
synchronized与Lock锁都可以用来保证线程安全,二者均属于悲观锁、都具备基本的互斥、同步、锁重入功能,注意synchronized不可中断
- 一. 锁的获取方式不同:synchronized是一种隐式锁,线程在进入同步代码块或同步方法时自动获取锁,并在退出同步代码块或者同步方法时释放锁,使用简单,不需要手动获取锁和释放锁,发生异常会自动释放锁。Lock是一种显式锁,线程需要手动获取锁,通过lock()方法获取锁,通过unlock()方法释放锁,另外,Lock还提供了获取非阻塞的竞争锁的方法tryLock(),这个方法可以通过返回true或者false来告诉当前线程是否已经有其它线程正在使用锁,如果当前锁没有被其它线程占用,tryLock()方法会立即返回true,表示当前线程成功获取了锁,如果返回false,则意味着当前锁已经被其它线程占用了,当前线程无法立即获得锁;而synchronized是关键字,无法扩展实现非竞争阻塞锁的方法,synchronized只有代码块执行结束或者代码出现异常时才会释放锁,因为它对锁的释放是被动的。
- 二. 锁的释放方式不同,synchronized是自动释放锁,线程执行完同步代码块或同步方法后会自动释放锁。lock是手动释放锁,线程需要在finally代码块中显示调用unlock()方法来释放锁,以确保锁被正确释放,否则可能会导致死锁等问题。
- 三. 功能不同,synchronized只能实现独占锁,即同一时间只能有一个线程获取到锁并访问共享资源,其他线程需要等待。lock可以实现独占锁和共享锁,独占锁与synchronized功能一样,共享锁可以让多个线程同时访问共享资源,从而提高程序的并发性能。
- 四. 性能不同,在低并发的情况下,synchronized的性能优于lock,但在高并发的情况下,lock的性能更好,因为synchronized在释放锁的时候会唤醒所有等待在该锁上的线程,而lock可以精确控制哪个线程被唤醒,从而减少上下文切换的次数,提高程序的性能。
- 五. 锁的公平性:Synchronized不保证锁的公平性,而Lock可以通过构造函数来选择是公平锁还是非公平锁。
- 需要注意的是,synchronized是Java内置的一个线程同步关键字,而Lock是J.U.C包下面的一个接口,它有很多实现类,比如ReentrantLock就是它的一个实现类,synchronized可以给方法和代码块加锁,而Lock只能给代码块加锁,Lock需要手动获取锁和释放锁,容易出现忘记释放锁的情况,从而导致死锁等问题。因此,在使用Lock时需要非常谨慎。
- 并且Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态、公平锁、可打断、可超时、多条件变量
- Lock 有适合不同场景的实现,如 ReentrantLock,ReentrantReadWriteLock
- Lock有比synchronized更准确的线程语义和更好的性能
2. 谈谈类的加载机制
Java类的加载机制是指在Java程序运行期间,将类的字节码文件加载到JVM中的过程,Java类的加载机制主要包括以下三个步骤:
- 一. 加载。加载是指将类的字节码文件从磁盘或网络中读取到JVM的内存中。在加载阶段,JVM会查找必备定位字节码文件,并根据字节码文件的格式创建相应的Class对象。
- 二.链接。链接是指将类的二进制数据合并到JVM的运行状态中。链接阶段主要包括三个部分:验证、准备和解析。
- 验证阶段是确保类的字节码文件符合JVM规范的过程,包括检查字节码文件的格式、语法、语义等方面的问题,防止有恶意的代码对JVM造成影响。
- 准备阶段是为类的静态变量分配内存,并设置默认的初始值。这些变量在此阶段被赋值为默认值,如0、null等。
- 解析阶段是将类中的符号引用转换为直接引用的过程。在解析阶段,JVM会将常量池中的符号引用解析为直接引用,即确定类、字段、方法在内存中的具体位置。
- 三. 初始化。初始化是为类的静态变量赋值,并执行静态代码块的过程。在初始化阶段,JVM会执行类的静态变量赋值和静态代码块,将静态变量赋值为程序员指定的值。同时,JVM会保证类的初始化在多线程环境下是安全的。
3. 谈谈Object类的常用方法
Object类是Java中所有类的根类,它定义了一些基本的方法,可以在任何Java类中使用,主要有以下几个&#x