Software Construction Lab6心得

设计类的思路

1.Ladder类: 储存当前所有梯子的状况,即任意踏板上的猴子对象,无猴子则为 null。Ladder 对象在一次猴子过河中只创建一次,并且对所有猴子对象可见,且共

2.Monkey类:储存猴子的相关信息,每一个对象均可作为一个可运行的线程
Monkey 对象将会调用 Strategy 接口的子类,即调用策略
3.Strategy类:储存猴子的策略,由Strategy1、2、3组成。所有的策略类(Strategy1,Strategy2,Strategy3)是对接口 Strategy 的完善
4.MonkeyGenerator :负责生成实验所需梯子即猴子对象,同时改变参数,获得 实验数据

run()的执行流程思路

这里无需考虑具体采用的梯子选择策略。 猴子线程开始代表猴子已产生
step1:打印并日志猴子相关信息
step2: 每次决策开始时,猴子距离出生的时间+1s 。当猴子尚未上梯子,即处于原地观察状态时,需要进行策略选择 。得到决策结果后,猴子开始尝试移动,此时猴子之间产生竞争,需要进行线程同步,对线程上锁,并在结束移动时解锁 。 如果猴子已经在梯子上,则无需策略决定梯子,根据猴子的速度,依次查看可到达的踏板上是否有猴子即可;当猴子到达对岸时,跳出循环,线程执行结束。

注意:
1.移动开始时要上锁,结束时要解锁.
2.猴子到达最后一块踏板时,需要停顿 1s,等待下一次决策 。

策略选择

策略 1
设计:
优先选择没有猴子的梯子,若所有梯子上都有猴子,则优先 选择没有与我对向而行的猴子的梯子;若满足该条件的梯子有很多, 则随机选择 。
实现方案:
遍历所有梯子的所有踏板,根据 ladder,get(param1,param2)的返回值判断某块踏板上是否有猴子,得到没有猴子的梯子。如果所有梯子上都有猴子,根据
ladder,get(param1,param2)的返回梯子上的猴子对象的副本,再利用 Monkey 类的getDirection 方法得到猴子的行进方向,进行判断得到无相对而行的猴子的梯子。
如果没有满足上述条件的梯子,返回-1,代表无梯子可选,继续等待观察 。

策略 2
设计:
优先选择整体推进速度最快的梯子 (没有与我对向而行的猴子(条件 1)、梯子离我最近的猴子的真实行进速度最快(条件 2))
实现方案:
优先搜寻满足条件 1 的,如果有多个,再根据条件 2,挑选更合适的梯子返回,
如果多个梯子的条件 2 值相同,则随机返回。无满足条件 1 的梯子,则根据条件
2 挑选,如果多个梯子的条件 2 值相同,则随机返回。

如何确保 threadsafe?

1.在 ADT——Ladder 中,由于 Monkey 线程会对 Ladder 对象读写,因此 Ladder 中会被线程读写的属性 ladders 需要使用线程安全的包装类
2. 在 Monkey 线程执行的时候,由于多个 Monkey 线程之间会共享一个 Ladder 对象,因 此在线程对 Ladder 对象读写的时候容易导致竞争等问题出现,因此执行时,在适当的位 置,需要上锁与解锁。

输出方案设计

使用日志输出: 每次实验首先打印并记录参数,猴子线程开始执行时,打印猴子的属性值, 对于猴子从出生开始的每一秒的移动都会打印并记录 .用java.util包中的logger类实现。

猜你喜欢

转载自blog.csdn.net/jason1034538932/article/details/92398582
今日推荐