一、进程间通信(IPC)方法
在 Java 中,由于跨平台特性,部分 IPC 方式需要借助 JNI 或第三方库。以下是各方法的 Java 实现方案:
| 通信方式 | Java 实现方案 | 典型场景 |
|---|---|---|
| 管道(Pipe) | PipedInputStream / PipedOutputStreamProcessBuilder 结合 Runtime.exec() | 父子进程通信、Shell 命令链 |
| 信号(Signal) | sun.misc.Signal(不建议)ShutdownHook 处理进程终止 | 优雅停机、资源清理 |
| 消息队列 | RocketMQ / RabbitMQ / Kafka 或 JNI 调用 POSIX MQ | 分布式系统解耦 |
| 共享内存 | MappedByteBuffer(FileChannel.map)或 DirectByteBuffer + JNI | 高性能数据传输 |
| 信号量 | Semaphore(仅限线程)跨进程需用 FileLock 或第三方库 | 资源访问控制 |
| 套接字(Socket) | Socket / ServerSocket(TCP)DatagramSocket(UDP)UnixDomainSocket(Java 16+) | 网络通信、RPC |
二、Java 线程间通信(ITC)核心机制
1. 锁机制(Lock)
| 锁类型 | Java 实现 | 特点 | 适用场景 |
|---|---|---|---|
| 互斥锁 | synchronized / ReentrantLock | 排他性访问 | 大多数同步场景 |
| 读写锁 | ReentrantReadWriteLock | 读共享、写互斥 | 读多写少 |
| 自旋锁 | AtomicBoolean + CAS 循环 | 无上下文切换 | 锁持有时间极短 |
| 乐观锁 | AtomicInteger / LongAdder | 无锁并发 | 计数器、统计数据 |
// 1. synchronized(最常用)
public synchronized void safeMethod() {
// 临界区
}
// 2. ReentrantLock(更灵活)
Lock lock = new ReentrantLock();
lock.lock();
try {
// 临界区
} finally {
lock.unlock();
}
// 3. ReentrantReadWriteLock(读多写少)
ReadWriteLock rwLock = new ReentrantReadWriteLock();
rwLock.readLock().lock(); // 读锁
rwLock.writeLock().lock(); // 写锁
// 4. 自旋锁(AtomicBoolean)
AtomicBoolean flag = new AtomicBoolean(false);
while (!flag.compareAndSet(false, true)) {
// 自旋等待
}
2. 条件变量(Condition)
与 ReentrantLock 配合,实现 wait/notify 的增强版:
// 生产者-消费者经典实现
class BoundedBuffer {
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private final Object[] items = new Object[10];
private int putptr, takeptr, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await(); // 队列满,等待
}
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
count++;
notEmpty.signal(); // 唤醒消费者
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await(); // 队列空,等待
}
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
count--;
notFull.signal(); // 唤醒生产者
return x;
} finally {
lock.unlock();
}
}
}
3. synchronized + wait/notify(基础版)
// 使用 synchronized 内置锁的等待通知
synchronized (lock) {
while (condition) {
lock.wait(); // 释放锁并等待
}
// 执行操作
lock.notify(); // 唤醒一个等待线程
}
4. 线程局部存储(TLS)
// ThreadLocal - 每个线程独立副本
public class UserContext {
private static final ThreadLocal<Long> currentUserId = new ThreadLocal<>();
public static void setUserId(Long userId) {
currentUserId.set(userId);
}
public static Long getUserId() {
return currentUserId.get();
}
public static void clear() {
currentUserId.remove(); // 防止内存泄漏
}
}
// 使用 InheritableThreadLocal 传递上下文给子线程
InheritableThreadLocal<String> context = new InheritableThreadLocal<>();
context.set("parent-data");
new Thread(() -> System.out.println(context.get())).start(); // 子线程可继承
5. 信号量(Semaphore)
// 控制并发访问数(如连接池)
Semaphore semaphore = new Semaphore(3); // 最多3个并发
public void accessResource() {
try {
semaphore.acquire(); // 获取许可,阻塞
// 访问资源
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
semaphore.release(); // 释放许可
}
}
// tryAcquire - 非阻塞版本
if (semaphore.tryAcquire(1, TimeUnit.SECONDS)) {
// 获取成功
} else {
// 超时处理
}
6. 阻塞队列(BlockingQueue)
Java 并发包提供了丰富的线程安全队列:
// 最常用的无界队列
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
// 有界队列(避免内存溢出)
BlockingQueue<String> boundedQueue = new ArrayBlockingQueue<>(100);
// 延迟队列(延时任务)
DelayQueue<DelayedTask> delayQueue = new DelayQueue<>();
// 生产者-消费者模式
class Producer implements Runnable {
private final BlockingQueue<String> queue;
public void run() {
queue.put("data"); // 阻塞直到有空间
}
}
class Consumer implements Runnable {
private final BlockingQueue<String> queue;
public void run() {
String data = queue.take(); // 阻塞直到有数据
}
}
7. CompletableFuture(异步编程)
// 异步任务链
CompletableFuture<String> future = CompletableFuture
.supplyAsync(() -> fetchUserData()) // 异步执行
.thenApply(data -> processData(data)) // 转换结果
.thenAccept(result -> System.out.println(result))
.exceptionally(ex -> {
System.err.println("Error: " + ex);
return null;
});
// 等待多个任务完成
CompletableFuture.allOf(task1, task2, task3).join();
三、进程与线程通信对比(Java 视角)
| 对比维度 | 进程间通信(IPC) | 线程间通信(ITC) |
|---|---|---|
| 内存模型 | 不同进程独立内存空间 | 同一进程共享堆内存 |
| 数据共享 | 需 IPC 机制(Socket、共享内存) | 直接访问共享对象 |
| Java 实现 | ProcessBuilder / Socket / MappedByteBuffer | synchronized / volatile / BlockingQueue |
| 性能开销 | 较高(内核态切换、数据拷贝) | 较低(用户态操作) |
| 容错性 | 进程崩溃互不影响 | 线程崩溃导致整个 JVM 终止 |
| 同步复杂度 | 共享内存需要额外同步(FileLock) | 必须严格同步,否则出现竞态条件 |
| 分布式能力 | 支持跨机器通信(Socket) | 仅限单个 JVM 内部 |
四、性能对比一览
| 通信方式 | 延迟(约) | 吞吐量 | 适用场景 |
|---|---|---|---|
| 共享内存(MappedByteBuffer) | 极低(~100ns) | 极高(GB/s) | 高性能数据传输 |
| Unix Domain Socket | 低(~1μs) | 高(MB/s) | 本地进程通信 |
| TCP Socket | 中(~10μs) | 中 | 网络通信 |
| 管道(PipedStream) | 中(~1μs) | 中 | 父子线程通信 |
| 消息队列(MQ) | 高(~1ms) | 低 | 分布式解耦 |
| BlockingQueue | 低(~100ns) | 高 | 线程间数据缓冲 |
155



被折叠的 条评论
为什么被折叠?



