622 字
3 分钟
多线程并发编程笔记(多线程设计模式)
2025-10-29

多线程并发编程笔记#

多线程设计模式#

保护性暂停#

有一个结果需要从一个线程传递到另一个线程,让他们关联同一个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/NotifyPark/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/多线程并发编程笔记多线程设计模式/
作者
Thrinisty
发布于
2025-10-29
许可协议
CC BY-NC-SA 4.0