多线程--锁

一、锁是什么

锁是一种用于控制多个线程对共享资源访问的同步机制。它的主要作用是确保同一时刻只有一个线程可以访问共享资源,从而避免数据竞争和不一致性问题

锁的核心特性包括:

  • 互斥性:同一时刻只有一个线程可以持有锁
  • 可见性:锁的释放和获取操作会强制刷新线程的工作内存,确保共享变量的可见性
  • 可重入性:同一个线程可以多次获取同一把锁

二、多线程中的锁分类

多线程中的锁可以根据不同的标准进行分类

1、按锁的实现方法

1、内置锁(synchronized)

  • Java提供的关键字,基于JVM实现

  • 使用简单,但功能有限

    public synchronized void method() {
        // 同步代码
    }	
    

2、显式锁(ReentrantLock)

  • java.util.concurrent.locks包下的锁实现

  • 功能更强大,支持公平锁、可中断锁、超时获取锁等

    Lock lock = new ReentrantLock();
    lock.lock();
    try {
        // 同步代码
    } finally {
        lock.unlock();
    }
    

2、按锁的特性

1、可重入锁

  • 同一个线程可以多次获取同一把锁
  • 例如:synchronized和ReentrantLock

2、不可重入锁

  • 同一个线程只能获取一次锁
  • 例如:NonReentrantlock(需要自定义实现)

3、公平锁

  • 按照线程请求锁的顺序分配锁
  • 例如:ReentrantLock(true)

4、非公平锁

  • 不保证线程获取锁的顺序
  • 例如:synchronized和ReentrantLock(false)

3、按锁的粒度

1、粗粒度锁

  • 锁的粒度较大,保护整个资源或方法
  • 例如:synchronized修饰整个方法

2、细粒度锁

  • 锁的粒度较小,保护部分资源或代码块
  • 例如:synchronized修饰代码块,或适用多个ReentrantLock

4、按锁的状态

1、乐观锁

  • 假设没有冲突,直接操作数据,如果发现冲突则重试
  • 例如:CAS操作、Atomic类

2、悲观锁

  • 假设会发生冲突,先加锁再操作数据
  • 例如:synchronized和ReentrantLock

5、按锁的功能

1、读写锁(ReentrantReadWriteLock)

  • 支持读锁和写锁分离,读操作可以并发,写操作互斥

    ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
    Lock readLock = lock.readLock();
    Lock writeLock = lock.writeLock();
    

2、条件变量(Condition)

  • 用于线程间的协作,类似于wait()和notify()

    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
    condition.await();  // 等待
    condition.signal(); // 唤醒
    

3、自旋锁

  • 线程在获取锁失败时,不会阻塞,而是循环尝试获取锁
  • 适用于锁竞争不激烈的场景

4、分布式锁

  • 用于分布式系统中,确保多个节点之间的同步
  • 例如:基于Redis或ZooKeeper实现的分布式锁

三、常见锁的实现

1、synchronized

  • 内置锁,基于JVM实现
  • 支持可重入性,但不支持公平锁、可中断锁等功能

2、ReentrantLock

  • 显示锁,基于AQS(AbstractQueuedSynchronizer)实现
  • 支持公平锁、可中断锁、超时获取锁等功能

3、ReentrantReadWriteLock

  • 读写锁,支持读锁和写锁分离
  • 读锁是共享锁,写锁是独占锁

4、StampedLock

  • Java8引入的锁,支持乐观读锁、悲观读锁和写锁
  • 性能优于ReentrantReadWriteLock

5、Atomic类

  • 基于CAS实现的无锁操作
  • 适用于简单的原子操作

四、锁的应用场景

1、synchronized

  • 适用于简单的同步场景,例如保护共享变量或方法

2、ReentrantLock

  • 适用于复杂的同步场景,例如需要公平锁、可中断锁或超时获取锁

3、ReentrantReadWriteLock

  • 适用于读多写少的场景,例如缓存系统

4、StampedLock

  • 适用于高并发读场景,例如统计系统

5、Atomic类

  • 适用于低竞争场景,例如计数器

五、锁的优缺点

优点

  1. 保证线程安全:避免数据竞争和不一致性问题。
  2. 支持复杂同步逻辑:例如条件变量、读写锁等。

缺点

  1. 性能开销:锁的获取和释放会带来性能开销。
  2. 死锁风险:如果锁的使用不当,可能导致死锁。
  3. 复杂性:显式锁需要手动管理锁的获取和释放。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值