1.谈谈synchronized与Lock锁的区别?
synchronized与Lock锁都可以用来保证线程安全
- 一. 锁的获取方式不同:synchronized是一种隐式锁,线程在进入同步代码块或同步方法时自动获取锁,并在退出同步代码块或者同步方法时释放锁,使用简单,不需要手动获取锁和释放锁,发生异常会自动释放锁。Lock是一种显式锁,线程需要手动获取锁,通过lock()方法获取锁,通过unlock()方法释放锁,
- 二. 锁的释放方式不同,synchronized是自动释放锁,线程执行完同步代码块或同步方法后会自动释放锁。lock是手动释放锁,线程需要在finally代码块中显示调用unlock()方法来释放锁,以确保锁被正确释放,否则可能会导致死锁等问题。
- 三. 功能不同,synchronized只能实现独占锁,即同一时间只能有一个线程获取到锁并访问共享资源,其他线程需要等待。lock可以实现独占锁和共享锁,独占锁与synchronized功能一样,共享锁可以让多个线程同时访问共享资源,从而提高程序的并发性能。
- 四. 性能不同,在低并发的情况下,synchronized的性能优于lock,但在高并发的情况下,lock的性能更好,因为synchronized在释放锁的时候会唤醒所有等待在该锁上的线程,而lock可以精确控制哪个线程被唤醒,从而减少上下文切换的次数,提高程序的性能。
- 五. 锁的公平性:Synchronized不保证锁的公平性,而Lock可以通过构造函数来选择是公平锁还是非公平锁。
- 需要注意的是,synchronized是关键字,而Lock是接口,synchronized可以给方法和代码块加锁,而Lock只能给代码块加锁,Lock需要手动获取锁和释放锁,容易出现忘记释放锁的情况,从而导致死锁等问题。因此,在使用Lock时需要非常谨慎。
2. 谈谈类的加载机制
Java类的加载机制是指在Java程序运行期间,将类的字节码文件加载到JVM中的过程,Java类的加载机制主要包括以下三个步骤:
- 一. 加载。加载是指将类的字节码文件从磁盘或网络中读取到JVM的内存中。在加载阶段,JVM会查找必备定位字节码文件,并根据字节码文件的格式创建相应的Class对象。
- 二.链接。链接是指将类的二进制数据合并到JVM的运行状态中。链接阶段主要包括三个部分:验证、准备和解析。
- 验证阶段是确保类的字节码文件符合JVM规范的过程,包括检查字节码文件的格式、语法、语义等方面的问题,防止有恶意的代码对JVM造成影响。
- 准备阶段是为类的静态变量分配内存,并设置默认的初始值。这些变量在此阶段被赋值为默认值,如0、null等。
- 解析阶段是将类中的符号引用转换为直接引用的过程。在解析阶段,JVM会将常量池中的符号引用解析为直接引用,即确定类、字段、方法在内存中的具体位置。
- 三. 初始化。初始化是为类的静态变量赋值,并执行静态代码块的过程。在初始化阶段,JVM会执行类的静态变量赋值和静态代码块,将静态变量赋值为程序员指定的值。同时,JVM会保证类的初始化在多线程环境下是安全的。
3. 谈谈Object类的常用方法
Object类是Java中所有类的根类,它定义了一些基本的方法,可以在任何Java类中使用,主要有以下几个:
- euqals()方法:用于比较两个对象是否相等,它默认使用的是对象的引用地址进行比较,如果需要比较对象的内容是否相等,需要在自定义类中重写equals方法。
- hashCode()方法,返回一个对象的哈希码,哈希码是一个32位的整数,主要用于在哈希表中存储对象。在自定义类中,如果需要将对象存储在哈希表中,需要重写hashCode方法。
- toString()方法,将一个对象转换为字符串形式并返回该字符串,默认情况下,Object类的toString方法返回的是对象的类名和一个哈希码。
- getClass()方法,获取一个Class类对象,可以用于获取对象的类名和类信息。
- wait(),notify()和notifyAll()方法,用于线程间的通信,其中wait()方法用于使当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。notify()方法用于随机唤醒一个等待该线程的对象,nbotifyAll()方法用于唤醒所有等待该对象的线程。
- finalize()方法,在垃圾回收器回收对象之前调用,用于释放对象所占用的资源和执行一些清理操作。
Object类提供了许多重要的方法&#