管道
在 Java 中,可以使用管道通过进程间通信。以下是一个简单的例子,展示了如何通过 ProcessBuilder
创建两个进程,并使用输入和输出流进行通信。
示例代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class ProcessCommunication {
public static void main(String[] args) {
try {
// 创建子进程
ProcessBuilder builder = new ProcessBuilder("java", "ChildProcess");
Process process = builder.start();
// 向子进程写数据
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream()), true)) {
writer.println("Hello from parent process!");
}
// 从子进程读取数据
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Received from child process: " + line);
}
}
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
// 子进程类
class ChildProcess {
public static void main(String[] args) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out), true)) {
// 从父进程读取数据
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Received from parent process: " + line);
// 向父进程发送响应
writer.println("Hello from child process!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
说明
-
父进程:
- 使用
ProcessBuilder
启动子进程。 - 通过
OutputStreamWriter
向子进程发送数据。 - 通过
InputStreamReader
接收子进程的数据。
- 使用
-
子进程:
- 使用
System.in
读取父进程发送的数据。 - 使用
System.out
发送响应回父进程。
- 使用
注意事项
- 确保
ChildProcess
类在同一个项目中可以被找到和执行。 - 管道通信适合简单数据交换,复杂通信可以考虑使用其他机制如 sockets 或消息队列。
消息队列
在 Java 中,使用消息队列进行进程间通信可以通过 Java Message Service (JMS) 实现。以下是一个简单的例子,展示了如何使用 ActiveMQ 作为消息队列。
环境设置
-
下载并安装 ActiveMQ:确保 ActiveMQ 正在运行。
-
添加依赖:如果使用 Maven,添加 ActiveMQ 的依赖。
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.16.3</version>
</dependency>
示例代码
消息生产者
import javax.jms.;
import org.apache.activemq.ActiveMQConnectionFactory;
public class MessageProducerExample {
public static void main(String[] args) {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
try (Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
Queue queue = session.createQueue("exampleQueue");
javax.jms.MessageProducer producer = session.createProducer(queue);
TextMessage message = session.createTextMessage("Hello from producer!");
producer.send(message);
System.out.println("Message sent: " + message.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
消息消费者
import javax.jms.;
import org.apache.activemq.ActiveMQConnectionFactory;
public class MessageConsumerExample {
public static void main(String[] args) {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
try (Connection connection = factory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
Queue queue = session.createQueue("exampleQueue");
javax.jms.MessageConsumer consumer = session.createConsumer(queue);
connection.start();
Message message = consumer.receive();
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
System.out.println("Received message: " + textMessage.getText());
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
说明
- ActiveMQConnectionFactory: 用于连接到 ActiveMQ 服务器。
- Session: 用于创建生产者、消费者和消息。
- Queue: 消息队列的名字,生产者和消费者使用相同的队列名进行通信。
- TextMessage: 用于发送和接收文本消息。
注意事项
- 确保 ActiveMQ 服务器正在运行,并在正确的端口上监听。
- 代码中的连接 URL (
tcp://localhost:61616
) 可能需要根据实际情况调整。 - 生产者和消费者可以在不同的进程中运行,甚至可以在不同的机器上,只要它们能够访问同一个 ActiveMQ 服务器。
信号量
在 Java 中,信号量通常用于线程间的同步,而不是进程间通信。进程间通信通常通过其他机制实现,如消息队列、管道、套接字等。不过,你可以使用共享文件或数据库结合信号量来模拟进程间通信。
下面是使用信号量进行线程间同步的示例:
示例代码
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
private static final Semaphore semaphore = new Semaphore(1);
public static void main(String[] args) {
Thread t1 = new Thread(new Worker("Thread 1"));
Thread t2 = new Thread(new Worker("Thread 2"));
t1.start();
t2.start();
}
static class Worker implements Runnable {
private final String name;
Worker(String name) {
this.name = name;
}
@Override
public void run() {
try {
System.out.println(name + " is waiting for a permit.");
semaphore.acquire();
System.out.println(name + " acquired a permit.");
// 模拟工作
Thread.sleep(2000);
System.out.println(name + " releasing permit.");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
}
说明
- Semaphore: 控制对共享资源的访问。
new Semaphore(1)
创建一个只有一个许可的信号量,类似于互斥锁。 - acquire(): 获取许可,如果没有可用的许可,线程将会被阻塞。
- release(): 释放许可,唤醒等待的线程。
进程间通信
如果你需要进程间通信,可以考虑使用以下机制:
- 文件:进程通过读写共享文件进行通信。
- 数据库:进程通过读写共享数据库记录进行通信。
- Sockets:使用网络套接字进行通信。
- 消息队列:如 JMS。
信号量本身在 Java 中不直接用于进程间通信,但可以作为同步机制与其他方法结合使用。
标签:操作系统,System,通信,println,import,进程,new,public From: https://www.cnblogs.com/DCFV/p/18417164