本文目录导读:

- 基础案例:线程的挂起与恢复
- 等待超时机制
- 生产者-消费者模式实现
- 可中断的等待(响应中断)
- 银行账户转账安全示例(实际应用场景)
- 高级案例:实现一个简单的AQS(AbstractQueuedSynchronizer)
- 注意事项与最佳实践
- 关键知识点总结
我将为你提供几个Java LockSupport 的实用案例,从基础到高级,帮助你理解线程阻塞与唤醒机制。
基础案例:线程的挂起与恢复
import java.util.concurrent.locks.LockSupport;
public class BasicLockSupportDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 开始执行");
// 阻塞当前线程,直到被唤醒
LockSupport.park();
System.out.println(Thread.currentThread().getName() + " 被唤醒,继续执行");
}, "Worker-Thread");
thread.start();
Thread.sleep(2000); // 主线程休眠2秒
System.out.println("主线程准备唤醒工作线程");
// 唤醒指定线程
LockSupport.unpark(thread);
}
}
等待超时机制
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.TimeUnit;
public class TimeoutLockSupportDemo {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("开始等待数据...");
// 最多等待5秒
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(5));
System.out.println("等待结束,继续执行");
});
thread.start();
// 主线程不主动唤醒,让工作线程超时自动继续
System.out.println("主线程不唤醒,让工作线程5秒后自动继续");
}
}
生产者-消费者模式实现
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.LockSupport;
public class ProducerConsumerWithLockSupport {
private static final Queue<Integer> QUEUE = new LinkedList<>();
private static final int MAX_SIZE = 5;
public static void main(String[] args) throws InterruptedException {
Thread consumerThread = new Thread(new Consumer(), "消费者");
Thread producerThread = new Thread(new Producer(), "生产者");
// 先启动消费者,确保它在等待中
consumerThread.start();
Thread.sleep(100);
producerThread.start();
}
static class Producer implements Runnable {
@Override
public void run() {
int count = 0;
while (count < 10) {
synchronized (QUEUE) {
if (QUEUE.size() < MAX_SIZE) {
QUEUE.add(count);
System.out.println("生产: " + count + ", 队列大小: " + QUEUE.size());
count++;
// 唤醒消费者
LockSupport.unpark(getConsumerThread());
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Consumer implements Runnable {
@Override
public void run() {
while (true) {
synchronized (QUEUE) {
if (QUEUE.isEmpty()) {
System.out.println("队列为空,消费者等待...");
LockSupport.park(); // 阻塞消费者
System.out.println("消费者被唤醒");
} else {
Integer item = QUEUE.poll();
System.out.println("消费: " + item + ", 队列大小: " + QUEUE.size());
if (item != null && item == 9) {
break; // 消费完成
}
}
}
}
}
}
private static Thread getConsumerThread() {
// 这里简化处理,实际需要记录消费者线程引用
return Thread.currentThread();
}
}
可中断的等待(响应中断)
import java.util.concurrent.locks.LockSupport;
public class InterruptibleParkDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
System.out.println("线程开始执行");
// 检查中断状态
Thread.currentThread().interrupt();
// 如果线程被中断,park会立即返回
LockSupport.park();
if (Thread.currentThread().isInterrupted()) {
System.out.println("线程被中断,park立即返回");
// 清除中断标志
Thread.interrupted();
}
System.out.println("继续执行");
});
thread.start();
thread.join();
System.out.println("主线程结束");
}
}
银行账户转账安全示例(实际应用场景)
import java.util.concurrent.locks.LockSupport;
public class BankTransferDemo {
static class BankAccount {
private String accountNo;
private double balance;
private Thread waitingThread; // 等待中的线程
public BankAccount(String accountNo, double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
public synchronized void transfer(BankAccount to, double amount) {
System.out.println(Thread.currentThread().getName() +
" 尝试从 " + accountNo + " 转账 " + amount + " 到 " + to.accountNo);
if (balance < amount) {
System.out.println("余额不足,等待资金到账...");
// 保存当前线程,以便唤醒
this.waitingThread = Thread.currentThread();
// 释放锁并阻塞
LockSupport.park();
// 唤醒后重新检查
if (balance < amount) {
System.out.println("唤醒后仍余额不足,再次等待");
LockSupport.park();
}
}
this.balance -= amount;
to.balance += amount;
System.out.println("转账完成,当前余额: " + balance);
// 唤醒等待的线程
if (to.waitingThread != null) {
LockSupport.unpark(to.waitingThread);
}
}
public void deposit(double amount) {
this.balance += amount;
System.out.println("存款后余额: " + balance);
// 存款后唤醒等待的线程
if (waitingThread != null) {
LockSupport.unpark(waitingThread);
}
}
}
public static void main(String[] args) throws InterruptedException {
BankAccount accountA = new BankAccount("A", 100);
BankAccount accountB = new BankAccount("B", 500);
// 线程1:从A转账500到B(余额不足)
Thread t1 = new Thread(() -> {
accountA.transfer(accountB, 500);
}, "转账线程-1");
// 线程2:向A存款600
Thread t2 = new Thread(() -> {
try {
Thread.sleep(2000); // 延迟存款
accountA.deposit(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "存款线程-2");
t1.start();
Thread.sleep(100);
t2.start();
t1.join();
t2.join();
}
}
高级案例:实现一个简单的AQS(AbstractQueuedSynchronizer)
import java.util.concurrent.locks.LockSupport;
public class SimpleAQS {
private volatile int state = 0; // 0:未锁定,1:已锁定
private Thread owner; // 当前持有锁的线程
private Thread head; // 等待队列头
private Thread tail; // 等待队列尾
private ConcurrentLinkedQueue<Thread> waitQueue = new ConcurrentLinkedQueue<>();
public void lock() {
// 尝试获取锁
if (compareAndSetState(0, 1)) {
owner = Thread.currentThread();
return;
}
// 获取失败,加入等待队列
waitQueue.add(Thread.currentThread());
// 自旋等待
while (true) {
if (compareAndSetState(0, 1)) {
owner = Thread.currentThread();
waitQueue.remove(Thread.currentThread());
return;
}
// 挂起当前线程
LockSupport.park();
}
}
public void unlock() {
if (owner != Thread.currentThread()) {
throw new IllegalMonitorStateException();
}
// 释放锁
state = 0;
owner = null;
// 唤醒下一个等待线程
Thread nextThread = waitQueue.poll();
if (nextThread != null) {
LockSupport.unpark(nextThread);
}
}
private boolean compareAndSetState(int expect, int update) {
// 这里简化处理,实际应该用AtomicInteger的CAS
if (state == expect) {
state = update;
return true;
}
return false;
}
}
// 测试类
class LockSupportAQSExample {
public static void main(String[] args) throws InterruptedException {
SimpleAQS lock = new SimpleAQS();
Runnable task = () -> {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 获得锁");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " 释放锁");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
};
// 创建多个线程竞争锁
for (int i = 0; i < 3; i++) {
new Thread(task, "线程-" + i).start();
}
Thread.sleep(5000);
}
}
注意事项与最佳实践
import java.util.concurrent.locks.LockSupport;
public class LockSupportBestPractices {
public static void main(String[] args) throws InterruptedException {
// 1. park和unpark不需要按照特定顺序
demonstrateOrderIndependence();
// 2. 可以提前unpark
demonstrateEarlyUnpark();
// 3. 中断不会影响unpark
demonstrateInterruptBehavior();
}
private static void demonstrateOrderIndependence() throws InterruptedException {
System.out.println("=== 演示1:unpark可以先于park执行 ===");
Thread t1 = new Thread(() -> {
Thread.currentThread().interrupt();
LockSupport.park();
System.out.println("即使先interrupt,也能唤醒");
});
t1.start();
t1.join();
}
private static void demonstrateEarlyUnpark() {
System.out.println("=== 演示2:提前unpark ===");
Thread t2 = new Thread(() -> {
// park会立即返回,因为已经有许可
LockSupport.park();
System.out.println("线程2立即执行");
});
LockSupport.unpark(t2); // 提前给许可
t2.start();
}
private static void demonstrateInterruptBehavior() throws InterruptedException {
System.out.println("=== 演示3:中断行为 ===");
Thread t3 = new Thread(() -> {
Thread.currentThread().interrupt(); // 设置中断标志
LockSupport.park(); // 会立即返回
System.out.println("线程3响应中断");
});
t3.start();
t3.join();
}
}
关键知识点总结
| 方法 | 功能 | 特点 |
|---|---|---|
park() |
阻塞当前线程 | 不可超时 |
parkNanos(nanos) |
带超时的阻塞 | 自动唤醒 |
unpark(thread) |
唤醒指定线程 | 可提前给许可 |
parkUntil(deadline) |
指定时间点唤醒 | 绝对时间 |
注意事项:
- LockSupport是基于许可(permit)机制的,unpark会发送许可
- 与Object的wait/notify不同,LockSupport不需要synchronized
- 每个线程最多只有一个许可
- 不会抛出InterruptedException,但会响应中断标志
- 比wait/notify更灵活,可以精确唤醒指定线程
这些案例覆盖了LockSupport的主要使用场景,从基础到实际应用,在实际项目中,它是构建高级并发工具的基础。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播