
在开始之前,推荐大家阅读一篇文章《Spring Web:深度解析与实战应用》https://cloud.tencent.com/developer/article/2472928,该文章深度解析了 Spring Web 模块,涵盖功能、原理、业务应用及实战示例与优缺点,有兴趣的朋友可以去了解下。
在多线程编程的世界里,锁是保障共享资源安全访问的重要机制。而公平锁和非公平锁作为两种常见的锁实现方式,它们有着各自独特的性质与应用场景。本文将深入探讨公平锁和非公平锁的相关内容,帮助读者更好地理解并在实际开发中合理选用它们。
公平锁遵循先来先服务的原则,多个线程在竞争锁资源时,按照请求锁的先后顺序依次获得锁的使用权。就好比人们在排队购买火车票,谁先到售票窗口排队,谁就先被服务,不会出现后来者插队先拿到票的情况。当一个线程释放锁之后,处于等待队列头部的线程会被唤醒并获取锁,保证了每个线程获取锁的机会是公平的,不会出现某个线程长时间 “饥饿” 等待锁的现象。
ReentrantLock为例)在 Java 中,我们可以通过ReentrantLock类来创建公平锁,示例代码如下:
import java.util.concurrent.locks.ReentrantLock;
public class FairLockExample {
public static void main(String[] args) {
// 创建公平锁
ReentrantLock fairLock = new ReentrantLock(true);
Thread thread1 = new Thread(() -> {
try {
fairLock.lock();
System.out.println("线程1获取到锁");
// 模拟业务操作,这里简单睡眠一下
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fairLock.unlock();
System.out.println("线程1释放了锁");
}
});
Thread thread2 = new Thread(() -> {
try {
fairLock.lock();
System.out.println("线程2获取到锁");
} catch (Exception e) {
e.printStackTrace();
} finally {
fairLock.unlock();
System.out.println("线程2释放了锁");
}
});
thread1.start();
thread2.start();
}
}在上述代码中,ReentrantLock的构造函数传入true表示创建公平锁。线程 1 先启动去获取锁,在它持有锁并执行完业务操作释放锁之后,线程 2 才有机会获取到锁,严格按照请求顺序来分配锁资源。
非公平锁在多个线程竞争锁资源时,不会按照请求的先后顺序来分配锁,而是允许新到来的线程去 “抢占” 已经可以获取的锁,只要锁当前处于可用状态。就好像一群人在等公交车,虽然有些人已经等了一会儿,但车一来,后面刚到的人也有可能直接挤上车抢到座位,不需要严格按照先来后到的顺序。当一个线程释放锁后,新请求锁的线程和处于等待队列中的线程都有机会竞争获取锁,谁先抢到就是谁的。
ReentrantLock为例)以下是使用ReentrantLock创建非公平锁的示例代码:
import java.util.concurrent.locks.ReentrantLock;
public class UnfairLockExample {
public static void main(String[] args) {
// 创建非公平锁
ReentrantLock unfairLock = new ReentrantLock(false);
Thread thread1 = new Thread(() -> {
try {
unfairLock.lock();
System.out.println("线程1获取到锁");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
unfairLock.unlock();
System.out.println("线程1释放了锁");
}
});
Thread thread2 = new Thread(() -> {
try {
unfairLock.lock();
System.out.println("线程2获取到锁");
} catch (Exception e) {
e.printStackTrace();
} finally {
unfairLock.unlock();
System.out.println("线程2释放了锁");
}
});
thread1.start();
thread2.start();
}
}这里ReentrantLock构造函数传入false(其实不传默认就是非公平锁),线程 2 有可能在线程 1 还没释放锁之前就尝试去获取锁,在 1 释放锁的瞬间,2 也有机会直接获取到锁,而不一定是等待队列中的线程先获取。
总之,公平锁和非公平锁各有优劣,在实际的多线程编程中,需要根据具体的业务需求、对公平性的要求以及性能考量等多方面因素,来选择合适的锁机制,以实现高效且可靠的多线程并发操作。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。