Lab 6实验报告
1 实验目标概述
本次实验训练学生的并行编程的基本能力,特别是 Java 多线程编程的能力。 根据一个具体需求,开发两个版本的模拟器,仔细选择保证线程安全(threadsafe) 的构造策略并在代码中加以实现,通过实际数据模拟,测试程序是否是线程安全 的。另外,训练学生如何在 threadsafe 和性能之间寻求较优的折中,为此计算吞 吐率和公平性等性能指标,并做仿真实验。 Java 多线程编程 面向线程安全的 ADT 设计策略选择、文档化 模拟仿真实验与对比分析
2。
2 实验环境配置
Git指令连接仓库即可
3 实验过程
请仔细对照实验手册,针对三个问题中的每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 ADT设计方案
3.1.1 Monkey类
- 作用:实现于runnable接口,每个猴子作为一个线程,模拟猴子过河的过程
- 属性:mutable类型
- 方法:
(1)public void run()
Runnable的run方法重写,每隔1秒进行一次前进
(2)public Monkey(int id, int speed, int direction, List ladders)
猴子的构造方法
(3)private void jumptheladder1(Ladder ladder)
从左向右的猴子跳上第一个踏板
(4)private void jumptheladder2(Ladder ladder)
与上面的相同,改成从右向左
(5)private void forwardto1()
L->R根据速度,让猴子前进一次
(6)private void forwardto2()
R->L 与上面的相同
(7)private void LtoR1(List ladders)
private void LtoR2(List ladders)
private void LtoR3(List ladders)
private void RtoL1(List ladders)
private void RtoL2(List ladders)
private void RtoL3(List ladders)
三种选择梯子的策略,L->R,R->L分别三个,
4. Specification:
3.1.2 ladder类
- 作用:作为梯子,是踏板的载体,梯子的状态影响着猴子的选择
- 属性:mutable类
- 方法:
(1) public Ladder(int num, int id)
梯子的构造方法,构造的同时建立起踏板
(2)public boolean addtheon()
梯子上的猴子数量增加
(3)public boolean redtheon()
梯子上猴子的数量减少
剩下的为field中的get方法,详情见下方的spec
4. specification:
3.1.3 footstep类
- 作用:作为踏板,承载猴子,同时记录状态信息,供后方猴子前进时参考
- 属性:mutable类
- 方法:
(1)public Footstep(int num)
构造方法,num为踏板号
(2)public boolean changestate()
改变踏板状态
剩余的时field的get方法,详情见下方spec
4. Specification:
3.1.4 monkeyinitialize
该类是主程序类,实现了程序的初始化,gui的实现,吞吐率的计算,公平性的计算
-
public void initial() throws IOException
-
public void starts()
模拟器启动 -
public void visulize()
GUI界面 -
private void th()
计算吞吐率 -
private double fair()
计算公平性
3.1.5 mainapp
程序启动函数
3.2 Monkey线程的run()的执行流程图
这里无需考虑具体采用的梯子选择策略。
3.3 至少两种“梯子选择”策略的设计与实现方案
3.3.1 策略1
选择空梯子,没有的话则等待
3.3.2 策略2
先选择空闲梯子,没有的话,选择猴子最少的那个梯子
3.3.3 策略3(可选)
先选择空闲的梯子,若是没有的话,选择推进程度最远的那个梯子
3.4 “猴子生成器”MonkeyGenerator
利用scheduledexecutorservice创建一个单线程,
Run()内为生成k只猴子
service.scheduleAtFixedRate(start,0,t,TimeUnit.SECONDS);
设置为每t秒执行一次。即可完成生成器模拟。
当生成了指定数量的猴子时,结束任务。
如何确保threadsafe?
采用了synchronizedList来确保为线程安全的数据类型
当猴子移动而对梯子的状态发生修改时,synchronized(this)来进行代码段上锁
3.5 系统吞吐率和公平性的度量方案
按照实验手册所给出的公式,写出了相应的方法来计算吞吐率和公平性。
当然,吞吐率越大越好,公平性越接近1越好
3.6 输出方案设计
日志
每个猴子都有自己的日志
日志格式为 时间+行动信息
GUI
第一行显示配置信息,即梯子数等等
第二部分为简易的可视化
下侧为公平性和吞吐率,在全部过完河后显示
可视化(可选)
采用简易的0 1表示踏板,0表示没有猴子在踏板上,1表示该踏板上有猴子
动态刷新来达到可视化效果
3.7 猴子过河模拟器v1
3.7.1 参数如何初始化
采用配置文件从外部读取初始化信息
3.7.2 使用Strategy模式为每只猴子选择决策策略
三个策略,用随机数 1到3,产生个随机数来决定用哪个策略
3.8 猴子过河模拟器v2
在不同参数设置和不同“梯子选择”模式下的“吞吐率”和“公平性”实验结果及其对比分析。
3.8.1 对比分析:固定其他参数,选择不同的决策策略
固定参数 n=5 h=20 t=1 N=20 k=5 MV=6
3.8.2 对比分析:变化某个参数,固定其他参数
相对于3.8.1 改变n=10
改变h=10
改变t=2
改变N=50
该变k=10
改变MV=12
(这东西真的费时间)
3.8.3 分析:吞吐率是否与各参数/决策策略有相关性?
通过上一步的数据,很明显可以看出
决策策略于吞吐率明显相关
与各参数也有关
增加梯子数量,减少踏板数量均可增加吞吐率
增加速度上限也可增加吞吐率
增加单次产生的猴子数量对吞吐率的改变不明显
增加猴子总量一定程度上增加了吞吐率
3.8.4 压力测试结果与分析
压力测试1:
n=5 h=10 t=1 N=100 k=20 MV=6,猴子密集产生
可以看出,三种测略的吞吐率都明显上升,但不是太高,策略1和测略3的公平性很高。可能是由于猴子产生时很快可以找到梯子,且整体推进速度较快。
压力测试2:
n=10 h=20 t=1 N=50 k=10 MV=50,速度跨度很大,即速度差异大
可以看出,速度范围很大,所以基本不会造成梯子的紧张,三个测略的吞吐率都很大且差距相近,特别是公平性
3.9 猴子过河模拟器v3
针对教师提供的三个文本文件,分别进行多次模拟,记录模拟结果。
吞吐率 公平性
Competiton_1.txt
平均值 4.432 0.78
Competiton_2.txt
平均值 7.939 0.752
Competiton_3.txt
平均值 2.151 0.749
成