一、实验目的:
- 通过编写多线程并发和进程通信的模拟代码,加深对多线程编程和进程通信的理解。
- 学习如何使用Java中的多线程和管道流来实现并发执行和进程间通信。
- 掌握多线程的基本概念和使用方法,以及进程通信的实现方式。
实验设备与实验环境: 计算机,Java编译系统,idea,ChatGPT 二、实验程序设计内容: 实验分为两部分:一部分是多线程并发(Exam_2.1),另一部分是进程通信(Exam_2.2)。
- Exam_2.1部分:用户输入并发进程的数量和执行次数,创建对应数量的线程,每个线程执行指定次数的任务并输出执行信息。
- Exam_2部分:使用管道流进行进程间通信,主线程创建子线程往管道中写入数据,主线程读取子线程写入的数据并输出。
三、实验程序设计思路及流程图
- 在Exm2_1方法中,用户输入并发进程的数量和执行次数,创建对应数量的线程对象,并启动这些线程。
- 每个线程对象是myThread类的实例,其中包含线程的ID和执行次数。线程运行时输出对应的执行信息,并通过Thread.sleep模拟执行过程。
- 在Exm2_2方法中,使用PipedInputStream和PipedOutputStream创建管道流,并连接起来。
- 创建子线程写入数据到管道中,在子线程中调用myPipe.writeToPipe方法,用户输入要发送给父进程的消息,写入管道后关闭输出流。
- 主线程读取管道中的数据并输出,同时等待子线程结束。通过这种方式实现了进程间的通信。
- 在myPipe类中,实现了写入管道的方法,用户输入消息后将消息写入管道。
四、实验源程序及注释: package homework.os;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/**
* Date:2024/3/11 8:23
* Description:TODO
*
* @author Leon
* @version 1.0
*/
public class exm2 {
public static void main(String[] args) {
System.out.println("Please input the experiment you want to select \n" +
"(1-Exam_2.1(thread) | 2-Exam_2.2(pipe)");
if (new Scanner(System.in).nextInt() == 1) Exm2_1();
else Exm2_2();
}
static void Exm2_1() {
Scanner sc = new Scanner(System.in);
List<Thread> tList = new LinkedList<>();
System.out.println("Please enter the number of concurrent processes");
int n = sc.nextInt();
System.out.println("Please enter the number of process executions");
int m=sc.nextInt();
for (int i = 1; i <= n; i++)
tList.add(new myThread(i,m));
for (Thread t : tList)
t.start();
for (Thread t : tList)
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread exiting");
}
static void Exm2_2() {
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
try {
out.connect(in);
// 创建子线程写数据到管道
Thread writerThread = new Thread(() -> {
try {
myPipe.writeToPipe(out);
} catch (IOException e) {
e.printStackTrace();
}
});
writerThread.start();
// 读取数据从管道
byte[] buffer = new byte[1024];
int bytesRead = in.read(buffer);
String receivedMessage = new String(buffer, 0, bytesRead);
System.out.println("Received from child process: " + receivedMessage);
writerThread.join(); // 等待子线程结束
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
class myThread extends Thread {
private int threadId;
private int exe;
public myThread(int threadId,int exe) {
this.threadId = threadId;
this.exe=exe;
}
@Override
public void run() {
for (int i = 1; i <= exe; i++) {
System.out.println("Thread " + threadId + " is running: 第" + i + "次执行");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class myPipe {
static void writeToPipe(PipedOutputStream out) throws IOException {
System.out.println("Enter the message to send to the parent process: ");
String message = new Scanner(System.in).nextLine();
out.write(message.getBytes());
out.close();
}
} 五、实验程序测试过程及解释说明 1.多线程并发 Please input the experiment you want to select (1-Exam_2.1(thread) | 2-Exam_2.2(pipe) 1 Please enter the number of concurrent processes 5 Please enter the number of process executions 3 2.进程通信 Please input the experiment you want to select (1-Exam_2.1(thread) | 2-Exam_2.2(pipe) 2 Enter the message to send to the parent process: A1高闪来一个,秋梨膏 六、实验程序测试过程与结果分析、 1.多线程并发 Thread 1 is running: 第1次执行 Thread 5 is running: 第1次执行 Thread 4 is running: 第1次执行 Thread 2 is running: 第1次执行 Thread 3 is running: 第1次执行 Thread 2 is running: 第2次执行 Thread 4 is running: 第2次执行 Thread 3 is running: 第2次执行 Thread 1 is running: 第2次执行 Thread 5 is running: 第2次执行 Thread 2 is running: 第3次执行 Thread 3 is running: 第3次执行 Thread 5 is running: 第3次执行 Thread 4 is running: 第3次执行 Thread 1 is running: 第3次执行 Main thread exiting 2.进程通信 Received from child process: A1高闪来一个,秋梨膏 七、理论学习与实践能力锻炼方面的个人心得体会 通过本次实验,我深入了解了多线程并发和进程通信的实现方式。 多线程并发能够提高程序的执行效率,同时需要注意线程间的同步和互斥问题。 进程通信是不同进程之间进行数据交换和通信的重要方式,管道流是其中一种简单有效的实现方式。 通过实验,我对Java中多线程编程和进程通信有了更深入的理解,为以后的程序设计和开发积累了经验。 |