622 字
3 分钟
多线程并发编程笔记(多线程设计模式)
多线程并发编程笔记
多线程设计模式
保护性暂停
有一个结果需要从一个线程传递到另一个线程,让他们关联同一个GuardedObject,如果有结果不断从一个线程到另一个线程那么可以使用消息队列(生产者消费者)
JDK中join实现、Future实现采用的就是这种模式,因为要等待另一方的结果,因此归类到同步模式
public class GuardedObject {
public Object response;
public Object get() {
synchronized (this) {
while (response == null) {
try{
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return response;
}
}
public void complete(Object response) {
synchronized (this) {
this.response = response;
this.notifyAll();
}
}
}join在底层就是使用到的保护性暂停的设计模式
生产者消费者
消费队列可以用来平衡生产和消费的线程资源
生产者只负责生产结果数据,不关心数据该如何处理,而消费者专心处理结果数据
消息队列是有容量限制的,满时不会再加入数据,空的时候消耗数据
JDK中的阻塞队列使用的就是这种模式
package com.procus;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.LinkedList;
import java.util.Queue;
@AllArgsConstructor
public class MessageQueue {
//消息队列集合
private Queue<Message> queue = new LinkedList<>();
//容量
private int capacity;
//获取消息方法
public Message take() throws InterruptedException {
synchronized (queue) {
while (!queue.isEmpty()) {
queue.wait();
}
Message message = queue.poll();
queue.notifyAll();
return message;
}
}
public void put(Message message) throws InterruptedException {
synchronized (queue) {
while (queue.size() == capacity) {
queue.wait();
}
queue.add(message);
queue.notifyAll();
}
}
}
@Data
@AllArgsConstructor
class Message {
private int id;
private Object value;
}park/unpark
用于暂停和恢复线程,都是LockSupport类中的方法
| 特性 | Wait/Notify | Park/Unpark |
|---|---|---|
| 同步要求 | 必须在同步块(synchronized)中使用 | 不需要任何同步机制 |
| 精确唤醒 | notify()随机唤醒一个,notifyAll()唤醒所有 | 可以精确唤醒指定线程 |
| 顺序依赖性 | 必须先wait后notify,否则notify会丢失 | 可以先unpark后park,不会丢失信号 |
| 中断处理 | 被中断会抛出InterruptedException | 被中断不会抛出异常,但会立即返回 |
| 关联条件 | 通常与条件谓词一起使用 | 不关联任何条件,更底层 |
| 许可机制 | 无 | 基于许可(permit)的二进制信号量机制 |
| 锁释放 | wait()会自动释放锁 | park()不会释放任何锁 |
@Slf4j
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
log.info("start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("park");
LockSupport.park();
log.info("resume");
}, "t1");
t1.start();
Thread.sleep(2000);
log.info("unpack:t1");
LockSupport.unpark(t1);
}
} 多线程并发编程笔记(多线程设计模式)
https://thrinisty.github.io/Blog/posts/多线程并发编程笔记多线程设计模式/