嗨,大家好,欢迎来到程序猿漠然公众号,我是漠然。
亲爱的代码侠们,今天我们将走进Java的锁世界,探索那些锁定的秘密。在这个过程中,我会尽量让你们在笑声中学习,所以请准备好你的笑脸和耳朵,因为这是一场关于锁的喜剧之旅。
乐观锁:假设世界是美好的
乐观锁适用于更新操作频繁且冲突较少的情况。它通过CAS(Compare And Swap)操作来实现,如果更新成功,则直接进行修改;如果更新失败,则重新尝试。
想象一下,乐观锁就像是一个总是看到世界美好的一面的人。在Java中,这可以通过Atomic
类实现,比如AtomicInteger
。它会在更新数值时,先假设不会有其他线程来打扰它,然后再去检查一下是不是真的没有人抢它的风头。
csharp
import java.util.concurrent.atomic.AtomicInteger;
public class OptimisticLockerDemo {
private AtomicInteger count = new AtomicInteger(0);
public void addCount() {
int current;
do {
current = count.get();
// 假设没有人修改过计数器
} while (!count.compareAndSet(current, current + 1));
// 如果有竞争,这里会重试
}
}
悲观锁:小心翼翼的守门员
悲观锁适用于读写操作频繁且可能发生冲突的情况。它通过独占锁来确保同一时间只有一个线程可以访问资源。
悲观锁,就像是那个总是担心门外的世界充满了危险的人。在Java中,synchronized
关键字和ReentrantLock
就是这种锁的代表。它们在给你开门之前,会先确认一下是否有人在外面等着闯进来。
csharp
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PessimisticLockerDemo {
private final Lock lock = new ReentrantLock();
public void accessResource() {
lock.lock();
try {
// 这里是安全的代码区
} finally {
lock.unlock();
}
}
}
读写锁:有的放矢的守卫
读写锁(ReadWriteLock)允许多个读线程同时访问资源,但写线程在写入时需要独占访问权。这样,既可以提高读操作的并发性,又可以保证写操作的一致性。
读写锁就像是那个知道如何区分访客的人。在读写锁面前,读取动作是自由的,任何人都可以读,但写入动作则需要得到允许。
csharp
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockerDemo {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void readData() {
readWriteLock.readLock().lock();
try {
// 读操作
} finally {
readWriteLock.readLock().unlock();
}
}
public void writeData() {
readWriteLock.writeLock().lock();
try {
// 写操作
} finally {
readWriteLock.writeLock().unlock();
}
}
}
偏向锁:偏心的守候者
偏向锁旨在减少不必要的锁竞争开销。当锁主要被一个线程持有时,启用偏向模式可以提高性能,因为它会避免不必要的锁竞争检测。
偏向锁就像是那个只喜欢某个特定客户的服务员。在偏向锁的管理下,锁会偏爱第一个访问它的线程,就像服务员总是优先服务他最喜欢的顾客一样。
csharp
import java.util.concurrent.atomic.AtomicReference;
public class BiasedLockerDemo {
private final AtomicReference<Thread> owner = new AtomicReference<>();
public void doWork() {
Thread currentThread = Thread.currentThread();
if (owner.get() == null || owner.get() == currentThread) {
owner.set(currentThread);
// 偏向锁:当前线程独占锁
} else {
// 如果有其他线程竞争,则释放锁并重新竞争
owner.compareAndSet(currentThread, null);
owner.set(currentThread);
}
// 执行操作
}
}
轻量级锁:灵活的舞者
轻量级锁适用于竞争不激烈或短暂的锁需求。当没有竞争时,它通过CAS操作避免使用重量级的操作系统互斥量。
轻量级锁就像是那个在舞蹈中轻盈跳跃的舞者。当没有竞争时,它通过CAS操作旋转跳跃,就像是在跳一场只有一个人的华尔兹。
csharp
import java.util.concurrent.atomic.AtomicReference;
public class LightweightLockerDemo {
private final AtomicReference<Thread> owner = new AtomicReference<>();
public void doWork() {
Thread currentThread = Thread.currentThread();
```java
if (owner.get() == null) {
owner.compareAndSet(null, currentThread);
} else if (owner.get() != currentThread) {
// 轻量级锁:如果锁被其他线程持有,则尝试通过自旋等待
while (!owner.compareAndSet(currentThread, currentThread)) {
// 自旋等待
}
}
// 执行操作
}
}
自旋锁:不停转的舞者
自旋锁适用于锁被占用时间非常短的情况。线程在等待锁时不会进入等待状态,而是会循环检查锁的状态,这样可以减少线程状态切换的开销
自旋锁就像是那个在等待时也不会闲着的人。当线程尝试获取锁时,它不会直接放弃,而是会围着锁转来转去,就像是在跳一场不停旋转的探戈。
java
import java.util.concurrent.locks.LockSupport;
public class SpinningLockerDemo {
private final AtomicReference<Thread> owner = new AtomicReference<>();
public void doWork() {
Thread currentThread = Thread.currentThread();
while (!owner.compareAndSet(null, currentThread)) {
// 自旋等待
LockSupport.parkNanos(1); // 稍作停顿,然后继续自旋
}
// 执行操作
owner.compareAndSet(currentThread, null); // 释放锁
}
}
分段锁:聪明的物业管理者
分段锁适用于高度并发的场景,通过将数据分成多个段,可以减少锁竞争,提高系统的并发性能。
分段锁就像是那个把大楼分成不同区域,并为每个区域分配一个守门人的物业管理者。这样,每个守门人只负责自己的区域,避免了所有的访客都在大门口挤来挤去。
java
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.HashMap;
import java.util.Map;
public class SegmentedLockerDemo {
private final Map<Integer, Lock> locks = new HashMap<>();
public void accessResource(int segment) {
Lock lock = locks.computeIfAbsent(segment, k -> new ReentrantLock());
lock.lock();
try {
// 这里是安全的代码区
} finally {
lock.unlock();
}
}
}
希望这次关于Java锁的幽默之旅能让你们在笑声中学习到Java中锁的艺术。记住,锁的世界就像是一部复杂的芭蕾舞剧,每个角色都有自己的舞蹈,而我们的任务就是确保每个人都能跳得开心。
今天的分享就到这里,如果觉得对你有帮助,感谢点赞、分享、关注一波,你的认可是我创造的最大动力。
更多内容请关注公众号:程序猿漠然,一个分享有趣后端知识的公众号。