不可不说的Java“锁”事(Java锁机制详解:不可不知的核心要点)

原创
ithorizon 6个月前 (10-20) 阅读数 17 #后端开发

Java锁机制详解:不可不知的核心要点

一、Java锁机制概述

在Java并发编程中,锁是一种用于控制多个线程访问共享资源的机制。通过锁,我们可以保证同一时间只有一个线程可以访问共享资源,从而避免多线程并发致使的数据不一致和竞态条件问题。

二、Java锁的分类

Java中的锁重点分为以下几类:

  • 内置锁(Intrinsic Lock)/监视器锁(Monitor Lock)
  • 重入锁(ReentrantLock)
  • 读写锁(ReadWriteLock)
  • 条件锁(Condition)
  • 开朗锁和悲观失望锁
  • 偏向锁、轻量级锁和自旋锁

三、内置锁(Intrinsic Lock)/监视器锁(Monitor Lock)

内置锁是Java语言层面提供的锁机制,通过synchronized关键字实现。每个Java对象都可以作为锁。

public class SynchronizedExample {

public synchronized void synchronizedMethod() {

// 同步代码块

}

}

当线程访问synchronized方法或代码块时,线程会自动获取对象的内置锁,如果锁已被其他线程持有,则线程会等待锁释放。

四、重入锁(ReentrantLock)

重入锁是Java提供的一个显示锁,需要显式地加锁和解锁。ReentrantLock提供了比内置锁更充裕的功能,如可中断的锁获取、尝试非阻塞地获取锁、拥护公平锁等。

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {

private final ReentrantLock lock = new ReentrantLock();

public void lockMethod() {

lock.lock();

try {

// 同步代码块

} finally {

lock.unlock();

}

}

}

五、读写锁(ReadWriteLock)

读写锁是一种允许多个线程同时读取共享资源,但在写入共享资源时需要互斥的锁。ReadWriteLock提供了读锁(共享锁)和写锁(排他锁)。

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {

private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

public void readLockMethod() {

readWriteLock.readLock().lock();

try {

// 读取共享资源

} finally {

readWriteLock.readLock().unlock();

}

}

public void writeLockMethod() {

readWriteLock.writeLock().lock();

try {

// 写入共享资源

} finally {

readWriteLock.writeLock().unlock();

}

}

}

六、条件锁(Condition)

Condition是ReentrantLock的一个内部类,用于线程间的条件等待和通知。Condition提供了类似Object的wait()和notify()方法,但功能更强盛。

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.ReentrantLock;

public class ConditionExample {

private final ReentrantLock lock = new ReentrantLock();

private final Condition condition = lock.newCondition();

public void conditionWait() throws InterruptedException {

lock.lock();

try {

condition.await();

} finally {

lock.unlock();

}

}

public void conditionSignal() {

lock.lock();

try {

condition.signal();

} finally {

lock.unlock();

}

}

}

七、开朗锁和悲观失望锁

开朗锁和悲观失望锁是两种不同的锁策略。

  • 开朗锁:假设没有冲突出现,在更新数据时检查是否有其他线程同时修改数据,如果有冲突,则放弃操作。
  • 悲观失望锁:假设冲突一定会出现,在操作数据前先加锁,直到操作完成后再释放锁。

八、偏向锁、轻量级锁和自旋锁

Java虚拟机为了减成本时间锁的高效,引入了偏向锁、轻量级锁和自旋锁。

  • 偏向锁:假设锁重点被一个线程持有,通过消除不必要的锁竞争来减成本时间性能。
  • 轻量级锁:当没有竞争时,通过CAS操作避免使用重量级的操作系统互斥量。
  • 自旋锁:当线程尝试获取锁时,不会立即阻塞,而是循环检查锁是否可用,以减少线程状态切换的开销。

九、总结

Java锁机制是并发编程中不可或缺的一部分。明白和掌握不同的锁类型和策略,能够帮助我们更好地解决多线程并发问题,减成本时间程序的性能和稳定性。在实际开发中,我们需要采取具体场景选择合适的锁,并注意避免死锁、饥饿和活锁等并发问题。


本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门