编辑
2024-03-07
面试题库
0

等待/通知机制原理

等待/通知机制主要依赖于 Object 类的 wait()、notify() 和 notifyAll() 方法:

wait(): 当前线程进入等待状态,释放对象的监视器,并进入 WAITING 状态。它必须在 synchronized 块或方法内部调用。

notify(): 唤醒在对象监视器上等待队列中等待时间最长的线程,并将其移动到 BLOCKED 状态。它也必须在 synchronized 块或方法内部调用。

notifyAll(): 唤醒对象监视器上所有等待的线程,并将它们移动到 BLOCKED 状态。它也必须在 synchronized 块或方法内部调用。

等待/通知机制实现线程间通信

线程 A 调用 wait() 方法: 当前线程进入等待状态,释放对象的监视器,并进入 WAITING 状态。线程 A 等待线程 B 的通知。

线程 B 修改共享变量: 线程 B 执行 synchronized 块或方法,修改共享变量。

线程 B 调用 notify() 或 notifyAll() 方法: 线程 B 唤醒线程 A,将其移动到 BLOCKED 状态。线程 A 准备从 wait() 方法返回。

线程 A 获取锁并返回: 线程 A 获取对象的监视器,并从 wait() 方法返回,继续执行后续代码。

编辑
2024-03-06
面试题库
0

synchronized 的原理

synchronized 的核心原理在于锁定对象的监视器(Monitor)。每个对象都有一个与之关联的监视器,它控制着对象的访问权限。

获取锁: 当线程进入 synchronized 块或方法时,它会尝试获取对象的监视器。如果监视器已被其他线程占用,则当前线程会被阻塞,进入 BLOCKED 状态,等待锁的释放。

进入临界区: 获取锁的线程可以进入 synchronized 块或方法,执行临界区内的代码。临界区是指受 synchronized 保护的代码块,它确保同一时间只有一个线程可以执行。

释放锁: 线程执行完临界区代码后,会释放对象的监视器,其他被阻塞的线程可以尝试获取锁,进入临界区。

synchronized 的实现

方法同步: 使用 ACC_SYNCHRONIZED 标志表示方法为同步方法,并在方法调用和返回时使用 monitorenter 和 monitorexit 指令。

代码块同步: 使用 monitorenter 和 monitorexit 指令控制同步块的进入和退出。对象锁和类锁分别对应不同类型的 synchronized 使用方式。

synchronized 如何保证线程安全

排他性: 同一时间只有一个线程可以访问 synchronized 保护的代码块或方法。

可见性: 当一个线程修改共享变量时,其他线程能够立即看到这个修改,因为 synchronized 会将变量的值刷新到主内存。

原子性: synchronized 保护的代码块或方法是原子操作,即不会被其他线程打断。

编辑
2024-02-20
运维配置
0

服务器准备

ip备注
10.211.55.5

准备集群文件夹

shell
mkdir -p /opt/docker/redis-cluster/conf/{6001,6002,6003,6004,6005,6006}/data

准备镜像

shell
docker pull publicisworldwide/redis-cluster docker pull inem0o/redis-trib

准备docker-compose.yml文件

编辑
2024-02-15
面试题库
0

volatile 关键字具有以下特性

  • 可见性:保证被修饰的变量在被一个线程修改后,能立即被其他线程看到最新值,而不是从本地缓存中读取旧值。

  • 禁止指令重排序:确保 volatile 变量相关的操作不会被编译器或处理器重排序。

volatile 的原理主要基于以下几点

  • 内存屏障:在对 volatile 变量进行写操作时,会插入一个写屏障,强制将当前线程对应的本地内存中的共享变量值刷新到主内存。在读操作时,会插入一个读屏障,强制从主内存中读取最新的值到本地内存。

  • 缓存一致性协议:现代处理器通常使用缓存一致性协议(如 MESI 协议)来保证多个处理器缓存之间的数据一致性。当一个处理器修改了 volatile 变量,会通过缓存一致性协议通知其他处理器使对应的缓存行失效,从而保证其他处理器再次读取时从主内存获取最新值。

在一个多线程环境中,一个线程修改了 volatile 修饰的变量 flag 为 true ,另一个线程能够立即感知到这个变化并做出相应的处理。这是因为 volatile 的可见性特性保证了变量值的及时更新,避免了线程因为读取本地缓存中的旧值而导致的错误行为。同时,禁止指令重排序特性确保了相关操作的顺序不会被意外改变,从而增强了程序的可预测性和正确性。

编辑
2024-02-13
面试题库
0

happens-before 规则的定义

happens-before 规则是一种时间上的逻辑顺序,它定义了操作之间的执行顺序,并确保了程序执行结果的正确性。它包含以下两个条件:

如果一个操作 happens-before 另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。

两个操作之间存在 happens-before 关系,并不意味着 Java 平台的具体实现必须要按照 happens-before 关系指定的顺序来执行。如果重排序之后的执行结果,与按 happens-before 关系来执行的结果一致,那么这种重排序并不非法。