Java多线程经典题目(医院挂号)
- 2020 年 11 月 15 日
- 筆記
题目
实现一个医院的挂号机系统,要求:有多台挂号机同时运行,此时无论有多少患者挂号,要求都能挂到不同
的号码,并且要求实现当意外断电之后,下一次恢复还能从上次结束号码继续挂号?
* synchronized
* 文件操作
* IO流
解题思路
此题的难点在于这个断电,首先java处理断电续传等问题,一般我们使用RandomAccessFile这个流,因为它里面
有个seek方法,可以设置光标的偏移量,可以从超大的文本中快速定位我们的游标。所以我们可以将已经挂的号存
到一个新文件,然后每个线程执行挂号的时候都读取新文件的length长度作为seet的偏移量,以此来达到断电之后
也能从上次结束号码继续挂号。
源代码如下:
package com.thospital;
/**
* User:zhang
* Date:2020/11/10
**/
import java.io.*;
public class TestHospital {
public static void putNum(File file) {
try {
DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
for (int i = 1; i < 10001; i++) {
dos.writeInt(i);
}
dos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
RandomAccessFile r=new RandomAccessFile("d:\\a.txt","r");
// 下面不能用randomAccessFile,因为它是覆盖写,并且到达上次长度才能改变它的长度
DataOutputStream w = new DataOutputStream(new FileOutputStream("d:\\b.txt",true));
IOThread ioThread = new IOThread(r,w);
Thread thread1 = new Thread(ioThread, "挂号机一号");
Thread thread2 = new Thread(ioThread, "挂号机二号");
Thread thread3 = new Thread(ioThread, "挂号机三号");
Thread thread4 = new Thread(ioThread, "挂号机四号");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
class IOThread implements Runnable {
private RandomAccessFile ra=null;
private DataOutputStream wr=null;
private File file=new File("d:\\b.txt");
public IOThread(RandomAccessFile r, DataOutputStream w) {
this.ra = r;
this.wr = w;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true){
System.out.println("患者在" + name + "挂到了" + getNum() + "号");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized int getNum() {
try {
Thread.sleep(1000);
// 判断文件的长度就用文件的length
ra.seek(file.length());
int i = ra.readInt();
wr.writeInt(i);
if (i != -1) {
return i;
}else {
return -1;
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return 0;
}
}
```java