当前位置: 首页 > news >正文

百度面试题解析:synchronized、volatile、JMM内存模型、JVM运行时区域及堆和方法区(三)

#### 16. 说一下synchronized的修饰范围以及锁的部门?

`synchronized`是Java中实现线程同步的关键字,它可以修饰方法或代码块。通过`synchronized`关键字,Java能够保证在同一时刻只有一个线程可以执行被保护的代码块。

1. **修饰实例方法**:  
   当`synchronized`修饰实例方法时,它修饰的是对象的实例锁。每个对象都有一个唯一的实例锁,只有获取该锁的线程才能执行被`synchronized`修饰的方法。

   ```java
   public synchronized void someMethod() {
       // 同步代码
   }
   ```

2. **修饰静态方法**:  
   当`synchronized`修饰静态方法时,它修饰的是类级别的锁。类级别的锁是针对类的所有实例共享的,因此静态方法的同步是针对类的类锁。

   ```java
   public static synchronized void someStaticMethod() {
       // 同步代码
   }
   ```

3. **修饰代码块**:  
   `synchronized`还可以修饰代码块,确保只有一个线程能够执行特定的代码块。通常使用`synchronized(this)`或者`synchronized(ClassName.class)`来加锁。

   ```java
   public void someMethod() {
       synchronized (this) {
           // 同步代码
       }
   }
   ```

   - **锁的部门**:  
     锁的部门就是加锁的对象。例如:
     - 对于实例方法,锁是当前对象(`this`)。
     - 对于静态方法,锁是当前类的`Class`对象。
     - 对于代码块,锁是提供的对象。

#### 17. 了解volatile吗?都有哪些特性?分别举例子

`volatile`是Java中的一个轻量级同步机制,它确保了变量的可见性,即当一个线程修改了`volatile`变量的值,其他线程能立刻看到修改后的值。`volatile`变量不会被缓存到寄存器中,它直接从主内存读取。

**特性**:
1. **保证可见性**:  
   `volatile`修饰的变量在多个线程之间是可见的。修改一个`volatile`变量的线程会立刻将修改结果刷新到主内存,其他线程能立即读取到修改后的值。

   ```java
   private volatile boolean flag = false;

   public void changeFlag() {
       flag = true;  // 设置为true
   }

   public boolean checkFlag() {
       return flag;  // 立即反映flag的最新值
   }
   ```

2. **禁止指令重排**:  
   `volatile`禁止编译器和JVM对该变量的读写操作进行重排序优化。它会确保对`volatile`变量的操作在执行时的顺序是按照代码的顺序进行的。

   ```java
   private volatile int a = 0;

   public void setA() {
       a = 1;  // 第一行
       // 其他操作
   }

   public void printA() {
       System.out.println(a);  // 保证printA在setA之后才能看到a的最新值
   }
   ```

3. **不能保证原子性**:  
   `volatile`不能保证复合操作的原子性,如`i++`。如果需要复合操作的原子性,应该使用`synchronized`或`AtomicInteger`等机制。

   ```java
   private volatile int count = 0;

   public void increment() {
       count++;  // 不是原子操作
   }
   ```

#### 18. JMM内存模型

JMM(Java Memory Model)是Java虚拟机中用来定义多线程之间如何交互的内存模型。它规定了线程对共享变量的访问规则,保证了程序在多线程环境下的正确性。

- **工作内存**:每个线程都有自己的工作内存(缓存),即该线程的局部变量和对共享变量的缓存副本。
- **主内存**:所有线程共享的内存,存放所有的实例字段、静态字段和构成对象的字段。
- **规则**:
  1. **原子性**:基本的读写操作是原子的,但复合操作(如`i++`)不是原子的。
  2. **可见性**:一个线程对共享变量的修改必须立刻对其他线程可见(通过`volatile`、`synchronized`等机制)。
  3. **有序性**:Java编译器和JVM为了提高性能可能会进行指令重排,但JMM规定了一些发生顺序,以确保程序执行时的顺序符合预期(通过`synchronized`、`volatile`等控制顺序)。

#### 19. JVM运行时区域

JVM(Java Virtual Machine)运行时区域主要包括以下几部分:

1. **程序计数器**:  
   每个线程有一个程序计数器,它指示当前线程执行的字节码的行号。

2. **Java虚拟机栈**:  
   每个线程有一个私有的虚拟机栈,用于存储方法调用的局部变量、操作栈、方法返回地址等。每个方法调用时都会创建一个栈帧,方法结束时栈帧被销毁。

3. **本地方法栈**:  
   本地方法栈与Java虚拟机栈类似,但它用于支持JVM调用的本地方法。

4. **堆**:  
   堆是存放Java对象的地方,所有的对象实例和数组都分配在堆中。堆是JVM中最大的一块内存区域。

5. **方法区**:  
   方法区存储的是类的元数据、常量、静态变量和即时编译器编译后的代码。它是共享的,多个线程可以访问。

6. **直接内存**:  
   直接内存并不属于JVM运行时区域的一部分,但通过`java.nio`包,程序可以直接操作系统的内存。

#### 20. 堆、方法区和虚拟机栈分别是什么?存了什么?

- **堆**:  
  堆是JVM中存放对象实例和数组的地方,是Java内存中最大的一块区域。JVM会对堆进行垃圾回收。

- **方法区**:  
  方法区存储JVM加载的类信息、常量池、静态变量、即时编译器编译后的代码等。

- **虚拟机栈**:  
  虚拟机栈用于存储方法调用的栈帧,每个方法调用都会在栈中分配一个栈帧,栈帧中包含局部变量、操作数栈等信息。

#### 21. 方法区的版本变化以及内部常量池的变化?

- **方法区的版本变化**:  
  在早期的JVM实现中,方法区是堆的一部分,但在Java 8以后,方法区被移除并被称为**元空间(Metaspace)**。元空间不再在JVM堆中分配内存,而是使用本地内存。

- **常量池的变化**:
  - **JDK 7及以前**:常量池存储在方法区内。
  - **JDK 8及以后**:常量池被移到了堆中,变成了运行时常量池。原本存储在方法区的类元数据也被移到了元空间。

#### 22. 堆为什么要分成新生代和老年代?

JVM的堆被分为新生代(Young Generation)和老年代(Old Generation),主要是为了优化垃圾回收(GC)过程,减少GC的开销。

1. **新生代**:  
   新生代主要存放新创建的对象。新生代中的对象大部分生命周期短暂,因此GC频繁发生,但每次回收的代价较小。

2. **老年代**:  
   老年代用于存放存活较久的对象。因为老年代对象的生命周期较长,GC较少发生,但回收代价较大。

通过分代回收,JVM能够优化GC过程,提高性能。年轻代使用**Minor GC**,老年代使用**Major GC**或**Full GC**。

http://www.dtcms.com/a/512881.html

相关文章:

  • 快速创建Vue3项目
  • 网站备案邮寄到哪里网站备案是怎么回事
  • 建设一个人才网站需要的人才举报非法网站要求做笔录
  • 软件测试基础分类模型以及等价类练习实践
  • 网站建设运营公司大全宁夏省建设厅网站
  • 衡阳市城市建设投资有限公司网站站长之家查询网
  • spark组件-spark core(批处理)-rdd创建
  • 微前端(qiankun)使用教程
  • 婚纱网页制作seo技术306
  • 门户网站特点上海市网站建设公司
  • JS逆向之原型链补环境
  • 广西南宁做网站的公司小榄公司网站建设
  • 一个公司可以注册几个网站wordpress 获取友链
  • 部署大模型的API实战教程!
  • 手机版网站优化html5移动网站开发实例
  • 解释Python中的鸭子类型(Duck Typing)和它与静态类型语言的区别?
  • 数字营销网站建设国外在线crm酒店系统
  • pdw这个conda环境缺少cartopy这个库,将所有依赖下载后使用pip install ./*.whl离线安装,结果报错numpy版本不兼容
  • 用自己的电脑做视频网站微信推广
  • 强化学习2.2 MDP实践——Frozen lake
  • LeetCode 668.乘法表中第k小的数
  • 专业网站建设市场分析自媒体平台哪个收益高
  • 建设通网站怎么样网站如何做响应
  • Java 中的自引用
  • Cursor AI 技术架构、核心模型与技术参数全解析
  • 记录一次线上oom问题排查
  • 深度解析:通过ADO.NET驱动Kdbndp高效连接与操作Kingbase数据库
  • 网站排名怎么上去网站建设捌金手指花总二五
  • 上海做电子商务网站的公司快猫
  • Pycharm远程连接服务器项目