文章目录
- 概述
- 并发编程三大特性
- java中常见的锁
- synchronized关键字(隐式锁)
- ReentrantLock 类
- ReadWriteLock 接口
- StampedLock 类
- 小结
概述
在Java中,锁是用于控制多个线程对共享资源的访问的一种机制。它有两个主要作用:
保证线程安全
:多个线程同时访问共享资源时,锁可以保证线程的有序执行,避免出现竞争条件等线程安全问题。
提高性能
:通过锁的机制,可以提高多线程并发访问共享资源的效率,充分利用系统资源。
合理选择锁的类型可以避免不必要的线程阻塞,从而提高程序性能。
并发编程三大特性
原子性(Atomicity)
:原子性是指一个操作或者一组操作要么全部执行,要么全部不执行,不会被其他操作中途打断。
可见性(Visibility)
: 可见性是指当一个线程修改了共享变量的值后,其他线程能够立即看到这个修改。
有序性(Ordering)
:有序性是指程序执行的顺序应该与代码的书写顺序一致。但是由于指令重排序的存在,Java 程序的实际执行顺序可能与代码的书写顺序不一致。在 Java 中,可以使用 volatile 关键字禁止指令重排序。
java中常见的锁
synchronized关键字(隐式锁)
synchronized它的主要作用是确保在同一时刻只有一个线程可以访问被 synchronized 修饰的代码块
或方法
,以避免多线程之间的竞态条件和数据不一致问题。
public synchronized void synchronizedMethod() {
// 同步方法体
}
public void someMethod() {
//参数lockObject是一个对象引用 通常是一个用来作为锁对象的普通对象
synchronized (lockObject) {
// 同步代码块
}
}
ReentrantLock 类
ReentrantLock 是 Java 并发包中提供的一种可重入锁,它提供了比 synchronized 更灵活的锁机制。
ReentrantLock lock = new ReentrantLock();
lock.lock(); // 获取锁
try {
// 锁保护的代码块
} finally {
lock.unlock(); // 释放锁
}
ReadWriteLock 接口
ReadWriteLock 是一个读写锁接口,它包含了两个锁:读锁
和写锁
。读锁用于并发读取操作,多个线程可以同时持有读锁;写锁用于独占写入操作,只允许一个线程持有写锁
ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
readWriteLock.readLock().lock(); // 获取读锁
try {
// 读取操作
} finally {
readWriteLock.readLock().unlock(); // 释放读锁
}
readWriteLock.writeLock().lock(); // 获取写锁
try {
// 写入操作
} finally {
readWriteLock.writeLock().unlock(); // 释放写锁
}
StampedLock 类
StampedLock 是 Java 8 新增的一种读写锁实现,它提供了乐观读锁(optimistic read lock),悲观读锁(pessimistic read lock)和写锁(write lock)。StampedLock 的性能通常比 ReadWriteLock 更好,但使用时需要注意使用方式和适用场景。
StampedLock通过标记(stamp)
来识别锁的状态,从而确保线程安全性。
StampedLock stampedLock = new StampedLock();
//获取了一个乐观读锁的标记(stamp)乐观读锁它不会阻塞其他线程的写入操作,因此它适用于读多写少的场景。
long stamp = stampedLock.readLock();
try {
// 乐观读取操作
} finally {
stampedLock.unlockRead(stamp); // 释放乐观读锁
}
long stamp = stampedLock.writeLock(); // 获取写锁
try {
// 写入操作
} finally {
stampedLock.unlockWrite(stamp); // 释放写锁
}
小结
synchronized
关键字是最简单和最常用的锁机制之一,可以用于修饰方法或代码块,实现对象级别的锁定。它的优点是使用方便,但灵活性相对较低。
ReentrantLock
是一个可重入锁,提供了比 synchronized 更灵活的锁机制。它支持公平锁和非公平锁,以及可中断的锁等特性,适用于需要更复杂锁定方式的场景。
ReadWriteLock
是一个读写锁接口,包含了读锁和写锁。读锁适用于并发读取操作,写锁适用于独占写入操作。ReentrantReadWriteLock 是其实现类,提供了对读写锁的具体实现。
StampedLock
是 Java 8 新增的一种读写锁实现,提供了乐观读锁和悲观读锁等特性。相比于 ReadWriteLock,StampedLock 的性能通常更好。
比较:
StampedLock 适用于读多写少的场景(因为乐观读锁
),可以提供更好的性能;而 ReadWriteLock 则是传统的读写锁机制,适用于一般的读写操作场景。
觉得有用点个赞