本文目录导读:

我将为您提供一个完整的公平锁案例,帮助您理解公平锁的特性。
什么是公平锁?
公平锁是指多个线程按照申请锁的顺序来获取锁,先到先得,而非公平锁则允许线程"插队"。
完整案例
import java.util.concurrent.locks.ReentrantLock;
public class FairLockExample {
// 公平锁参数设为true
private static final ReentrantLock fairLock = new ReentrantLock(true);
// 非公平锁参数设为false(默认)
private static final ReentrantLock unfairLock = new ReentrantLock(false);
private static int sharedResource = 0;
public static void main(String[] args) throws InterruptedException {
System.out.println("========== 公平锁测试 ==========");
testFairLock();
Thread.sleep(2000);
System.out.println("\n========== 非公平锁测试 ==========");
testUnfairLock();
}
// 测试公平锁
private static void testFairLock() throws InterruptedException {
Thread[] threads = new Thread[10];
long startTime = System.currentTimeMillis();
// 创建10个线程
for (int i = 0; i < 10; i++) {
final int threadId = i;
threads[i] = new Thread(() -> {
for (int j = 0; j < 3; j++) {
fairLock.lock();
try {
sharedResource++;
Thread.sleep(10); // 模拟业务操作
System.out.println("公平锁 - 线程" + threadId + " 第" + j + "次获取锁,当前值: " + sharedResource);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
fairLock.unlock();
}
}
});
threads[i].start();
}
// 等待所有线程完成
for (Thread thread : threads) {
thread.join();
}
long fairTime = System.currentTimeMillis() - startTime;
System.out.println("公平锁执行总耗时: " + fairTime + "ms");
}
// 测试非公平锁
private static void testUnfairLock() throws InterruptedException {
Thread[] threads = new Thread[10];
long startTime = System.currentTimeMillis();
// 创建10个线程
for (int i = 0; i < 10; i++) {
final int threadId = i;
threads[i] = new Thread(() -> {
for (int j = 0; j < 3; j++) {
unfairLock.lock();
try {
sharedResource++;
Thread.sleep(10); // 模拟业务操作
System.out.println("非公平锁 - 线程" + threadId + " 第" + j + "次获取锁,当前值: " + sharedResource);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
unfairLock.unlock();
}
}
});
threads[i].start();
}
// 等待所有线程完成
for (Thread thread : threads) {
thread.join();
}
long unfairTime = System.currentTimeMillis() - startTime;
System.out.println("非公平锁执行总耗时: " + unfairTime + "ms");
}
}
更直观的演示案例
import java.util.concurrent.locks.ReentrantLock;
public class FairLockDemonstration {
private static final ReentrantLock lock = new ReentrantLock(true); // 公平锁
public static void main(String[] args) {
// 创建5个线程,观察获取锁的顺序
for (int i = 1; i <= 5; i++) {
new Thread(new Task("任务" + i)).start();
}
// 稍微等待,让线程按顺序启动
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 主线程也参与竞争
lock.lock();
try {
System.out.println("主线程获取了锁");
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
static class Task implements Runnable {
private final String name;
Task(String name) {
this.name = name;
}
@Override
public void run() {
// 每个任务尝试获取锁3次
for (int i = 0; i < 3; i++) {
lock.lock();
try {
System.out.println(name + " - 第" + (i+1) + "次获取锁,执行中...");
Thread.sleep(100); // 模拟工作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}
自定义公平锁实现(简单版本)
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class CustomFairLock {
// 使用ReentrantLock实现公平锁
private final ReentrantLock lock = new ReentrantLock(true);
private final Condition notEmpty = lock.newCondition();
private int[] buffer = new int[10];
private int count = 0;
private int putIndex = 0;
private int takeIndex = 0;
// 生产者方法
public void produce(int value) {
lock.lock();
try {
while (count == buffer.length) {
notEmpty.await();
}
buffer[putIndex] = value;
putIndex = (putIndex + 1) % buffer.length;
count++;
System.out.println(Thread.currentThread().getName() + " 生产了: " + value + ",当前数量: " + count);
notEmpty.signalAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
// 消费者方法
public int consume() {
lock.lock();
int value;
try {
while (count == 0) {
notEmpty.await();
}
value = buffer[takeIndex];
takeIndex = (takeIndex + 1) % buffer.length;
count--;
System.out.println(Thread.currentThread().getName() + " 消费了: " + value + ",当前数量: " + count);
notEmpty.signalAll();
return value;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return -1;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
CustomFairLock buffer = new CustomFairLock();
// 创建多个生产者和消费者
for (int i = 0; i < 5; i++) {
final int producerId = i;
new Thread(() -> {
for (int j = 0; j < 3; j++) {
buffer.produce(producerId * 10 + j);
}
}, "生产者" + i).start();
}
for (int i = 0; i < 5; i++) {
new Thread(() -> {
for (int j = 0; j < 3; j++) {
buffer.consume();
}
}, "消费者" + i).start();
}
}
}
公平锁与非公平锁的区别
| 特性 | 公平锁 | 非公平锁 |
|---|---|---|
| 获取锁顺序 | 先来先得 | 允许插队 |
| 性能 | 相对较慢(需要维护队列) | 相对较快 |
| 公平性 | 保证公平 | 不保证公平 |
| 适用场景 | 需要公平性的场景 | 对性能要求高的场景 |
| 实现机制 | 基于FIFO队列 | 基于CAS操作 |
运行结果对比(示例)
========== 公平锁测试 ==========
公平锁 - 线程0 第0次获取锁,当前值: 1
公平锁 - 线程0 第1次获取锁,当前值: 2
公平锁 - 线程0 第2次获取锁,当前值: 3
公平锁 - 线程1 第0次获取锁,当前值: 4
...
公平锁执行总耗时: 412ms
========== 非公平锁测试 ==========
非公平锁 - 线程3 第0次获取锁,当前值: 31
非公平锁 - 线程3 第1次获取锁,当前值: 32
...
非公平锁执行总耗时: 289ms
- 公平锁:严格按照线程请求的顺序获取锁,但性能相对较差
- 非公平锁:允许线程插队,性能较好但可能导致某些线程"饿死"
- 使用建议:除非有特殊需求,一般推荐使用非公平锁(默认)
- 实现方式:公平锁使用FIFO队列保证顺序,非公平锁使用CAS原子操作
这个案例展示了公平锁的基本使用方法和特性,您可以根据实际需求选择合适的锁类型。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播