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

Java 锁机制全面解析

在 Java 并发编程中,锁(Lock)是保证线程安全的关键工具。本文将全面介绍 Java 的锁机制,包括 synchronized 关键字、Lock 接口及其实现、读写锁、乐观锁与悲观锁等,帮助新手理解 Java 并发控制。

1. Java 中的锁概述

锁(Lock)用于控制多个线程对共享资源的访问。不同的锁机制可以提供不同的性能、可重入性、公平性和可中断性等特性。

2. synchronized 关键字

synchronized 是 Java 内置的同步机制,依赖于 Java 虚拟机(JVM)实现。

2.1 用法示例

public class SynchronizedExample {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
}

在上述示例中,increment 方法是同步方法,多个线程调用时会自动加锁,保证 count 变量的线程安全。

2.2 synchronized 作用范围

  • 同步实例方法:锁住当前实例(this)。
  • 同步静态方法:锁住类对象(Class)。
  • 同步代码块:可以锁定特定对象,提高并发性。
public void method() {
    synchronized (this) {
        // 代码块
    }
}

2.3 synchronized 的特性

  • 可重入性:一个线程获取锁后可以多次进入同步代码。
  • 不可中断:线程获取锁后,其他线程只能等待。
  • JVM 层面实现:使用 monitorentermonitorexit 指令。

3. Lock 接口(显式锁)

Lock 接口提供比 synchronized 更灵活的锁控制,主要实现类是 ReentrantLock

3.1 ReentrantLock 用法

import java.util.concurrent.locks.ReentrantLock;

public class LockExample {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }
}

3.2 ReentrantLock 特性

  • 可重入性:和 synchronized 类似,一个线程可以多次获得相同的锁。
  • 可中断:支持 lockInterruptibly() 方法,中断等待锁的线程。
  • 公平锁和非公平锁:默认非公平锁,可选择公平锁保证线程按请求顺序获取锁。
ReentrantLock fairLock = new ReentrantLock(true); // 公平锁

4. ReadWriteLock(读写锁)

ReadWriteLock 提供读锁(多个线程可读)和写锁(独占)。

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {
    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    private int data = 0;

    public int read() {
        lock.readLock().lock();
        try {
            return data;
        } finally {
            lock.readLock().unlock();
        }
    }

    public void write(int value) {
        lock.writeLock().lock();
        try {
            data = value;
        } finally {
            lock.writeLock().unlock();
        }
    }
}

5. 乐观锁与悲观锁

5.1 悲观锁

认为竞争严重,每次访问资源都加锁(synchronizedLock)。

5.2 乐观锁

认为竞争较少,使用 CAS(Compare And Swap) 机制,比如 AtomicInteger

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicExample {
    private final AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }
}

6. StampedLock(改进的读写锁)

StampedLock 提供乐观读锁,提高并发性能。

import java.util.concurrent.locks.StampedLock;

public class StampedLockExample {
    private final StampedLock lock = new StampedLock();
    private int data = 0;

    public int read() {
        long stamp = lock.tryOptimisticRead();
        int currentData = data;
        if (!lock.validate(stamp)) { // 检测数据是否被修改
            lock.readLock();
            try {
                currentData = data;
            } finally {
                lock.unlockRead(stamp);
            }
        }
        return currentData;
    }
}

7. ThreadLocal 变量

ThreadLocal 不是锁,而是让每个线程拥有自己的变量副本,避免锁竞争。

public class ThreadLocalExample {
    private static final ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);

    public void increment() {
        threadLocal.set(threadLocal.get() + 1);
    }
}

8. 选择合适的锁

锁类型特性适用场景
synchronizedJVM 层面,简单易用适合简单同步需求
ReentrantLock可中断、支持公平锁适合需要高级控制的场景
ReadWriteLock读写分离,提高并发读多写少的情况
StampedLock乐观读,提高性能适合高并发读的场景
ThreadLocal线程私有,无锁线程隔离数据

9. 总结

Java 提供了多种锁机制,每种锁都有其适用场景。synchronized 适用于简单同步,Lock 提供更多控制,ReadWriteLock 适用于读多写少的情况,StampedLock 提供乐观读锁以提高并发性能。此外,ThreadLocal 可用于无锁并发,避免数据竞争。

相关文章:

  • 【Linux】Ubuntu 24.04 LTS 安装 OpenJDK 8
  • 单表达式倒计时工具:datetime的极度优雅(智普清言)
  • 扩散模型算法实战——可控图像编辑
  • uniapp小程序,输入框限制输入(正整数、小数后几位)
  • `sscanf` 和 `scanf` 的区别
  • 磁盘清理工具-TreeSize Free介绍
  • 使用 QR-Code-Styling 在 Vue 3 中生成二维码
  • 【004安卓开发方案调研】之Ionic+Vue+Capacitor开发安卓
  • Z型隶属函数(Z-shaped Membership Function)的详细介绍及python示例
  • logisim安装以及可能出现的问题
  • _KiComputeTimerTableIndex函数分析
  • Excel筛选填充的正确方法
  • 在 Ubuntu 20.04 上重新启动网络
  • 掌握新编程语言的秘诀:利用 AI 快速上手 Python、Go、Java 和 Rust
  • 蓝桥杯真题 3513.岛屿个数
  • doris:时区管理
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.3.22)
  • 鱼书--学习2
  • Python入门基础
  • 【数据分享】2000—2024年我国省市县三级逐年归一化植被指数(NDVI)数据(年平均值/Shp/Excel格式)
  • 超越梅罗,这样一个亚马尔折射巴萨的容错率
  • 4月制造业PMI为49%,比上月下降1.5个百分点
  • 王毅:携手做世界和平与发展事业的中流砥柱
  • 国家统计局:一季度全国规模以上文化及相关产业企业营业收入增长6.2%
  • 北汽蓝谷一季度净亏损9.5亿元,拟定增募资不超60亿元
  • 十四届全国人大常委会举行第四十三次委员长会议 ,听取有关草案和议案审议情况汇报