一、实验目的
- 掌握多线程的基本概念,理解线程的状态、调度与优先级。
- 学会通过继承
Thread
类和实现Runnable
接口编写多线程程序。 - 理解线程资源的同步问题,掌握
synchronized
关键字和wait()
、notify()
方法的使用。 - 熟悉 Java 的任务定时处理,学会使用
Timer
和TimerTask
。 - 综合运用多线程的知识,设计并实现一个较为复杂的医院患者管理系统。
二、实验学时
2学时
三、实验类型
验证性
四、实验需求
1、硬件
每人配备计算机1台,建议优先使用个人计算机开展实验。
2、软件
安装IntelliJ IDEA,以及Java运行所需要的相关基础环境。
3、网络
本地主机能够访问互联网。
4、工具
无。
五、实验任务
- 继承
Thread
类实现多线程:模拟多个患者同时挂号。 - 实现
Runnable
接口编写多线程:模拟多个医生同时接诊。 - 线程资源的同步处理:使用
synchronized
关键字解决临界资源问题。 - 线程通信:使用
wait()
和notify()
方法实现患者与医生的交互。 - 任务定时处理:使用
Timer
和TimerTask
实现定时任务,如定期检查患者状态。
六、实验内容及步骤
任务 1:继承 Thread
类实现多线程
步骤:
- 设计一个
Patient
类继承Thread
类,模拟患者挂号的过程。
示例代码:
// Patient.java
public class Patient extends Thread {
private String name;
public Patient(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("患者 " + name + " 正在挂号...");
try {
Thread.sleep(1000); // 模拟挂号耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("患者 " + name + " 挂号完成。");
}
}
// 测试类
public class PatientTest {
public static void main(String[] args) {
Patient patient1 = new Patient("张三");
Patient patient2 = new Patient("李四");
Patient patient3 = new Patient("王五");
patient1.start();
patient2.start();
patient3.start();
}
}
任务 2:实现 Runnable
接口编写多线程
步骤:
- 设计一个
Doctor
类实现Runnable
接口,模拟医生接诊的过程。
示例代码:
// Doctor.java
public class Doctor implements Runnable {
private String name;
public Doctor(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("医生 " + name + " 正在接诊...");
try {
Thread.sleep(2000); // 模拟接诊耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("医生 " + name + " 接诊完成。");
}
}
// 测试类
public class DoctorTest {
public static void main(String[] args) {
Doctor doctor1 = new Doctor("王医生");
Doctor doctor2 = new Doctor("李医生");
Thread thread1 = new Thread(doctor1);
Thread thread2 = new Thread(doctor2);
thread1.start();
thread2.start();
}
}
任务 3:线程资源的同步处理
步骤:
- 设计一个
Hospital
类,模拟医院挂号系统的临界资源问题。 - 使用
synchronized
关键字解决多线程并发访问问题。
示例代码:
// Hospital.java
public class Hospital {
private int availableNumbers = 10; // 剩余挂号数量
// 挂号方法
public synchronized void register(Patient patient) {
if (availableNumbers > 0) {
System.out.println("患者 " + patient.getName() + " 挂号成功,剩余号数: " + --availableNumbers);
} else {
System.out.println("患者 " + patient.getName() + " 挂号失败,号已挂完。");
}
}
}
// Patient.java
public class Patient extends Thread {
private String name;
private Hospital hospital;
public Patient(String name, Hospital hospital) {
this.name = name;
this.hospital = hospital;
}
@Override
public void run() {
hospital.register(this);
}
}
// 测试类
public class HospitalTest {
public static void main(String[] args) {
Hospital hospital = new Hospital();
for (int i = 1; i <= 15; i++) {
Patient patient = new Patient("患者" + i, hospital);
patient.start();
}
}
}
任务 4:线程通信
步骤:
- 使用
wait()
和notify()
方法实现患者与医生的交互。 - 模拟患者等待医生接诊的过程。
示例代码:
// Clinic.java
public class Clinic {
private boolean isDoctorAvailable = false;
// 患者等待医生接诊
public synchronized void waitForDoctor(Patient patient) {
while (!isDoctorAvailable) {
try {
System.out.println("患者 " + patient.getName() + " 正在等待医生...");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("患者 " + patient.getName() + " 被医生接诊。");
}
// 医生接诊患者
public synchronized void consultPatient(Doctor doctor) {
System.out.println("医生 " + doctor.getName() + " 开始接诊。");
isDoctorAvailable = true;
notifyAll();
}
}
// Patient.java
public class Patient extends Thread {
private String name;
private Clinic clinic;
public Patient(String name, Clinic clinic) {
this.name = name;
this.clinic = clinic;
}
@Override
public void run() {
clinic.waitForDoctor(this);
}
}
// Doctor.java
public class Doctor extends Thread {
private String name;
private Clinic clinic;
public Doctor(String name, Clinic clinic) {
this.name = name;
this.clinic = clinic;
}
@Override
public void run() {
clinic.consultPatient(this);
}
}
// 测试类
public class ClinicTest {
public static void main(String[] args) {
Clinic clinic = new Clinic();
Patient patient1 = new Patient("张三", clinic);
Patient patient2 = new Patient("李四", clinic);
Doctor doctor = new Doctor("王医生", clinic);
patient1.start();
patient2.start();
doctor.start();
}
}
任务 5:任务定时处理
步骤:
- 使用
Timer
和TimerTask
实现定时任务,如定期检查患者状态。
示例代码:
import java.util.Timer;
import java.util.TimerTask;
// PatientMonitor.java
public class PatientMonitor {
public static void main(String[] args) {
Timer timer = new Timer();
// 定时任务:每5秒检查一次患者状态
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("正在检查患者状态...");
// 模拟检查逻辑
System.out.println("患者状态正常。");
}
}, 0, 5000); // 延迟0毫秒,每隔5000毫秒执行一次
}
}
七、实验考核
本实验考核采用【实验随堂查】方式开展。
每个实验完成后,在实验课上通过现场演示的方式向实验指导教师进行汇报,并完成现场问答交流。
每个实验考核满分100分,其中实验成果汇报60分,现场提问交流40分。
实验考核流程:
(1)学生演示汇报实验内容的完成情况,实验指导老师现场打分。
(2)指导老师结合实验内容进行提问,每位学生提问2-3个问题,根据回答的情况现场打分。
(3)实验考核结束后,进行公布成绩。