software construction in Java Lab6

Lab 6 主要解决的是猴子过河的问题。

本实验的场景是这样的,有一条河,河上有n个梯子,每个梯子的长度为h,现在每隔t秒生成k个猴子(速度,方向均是随机的),猴子的总数一共是N个,猴子一共有三个属性,ID ,方向,还有速度,猴子通过选择不同的梯子,过河,到达河对岸即算成功。

具体的细节解释:

每个猴子过河的速度不同,其速度??定义为每秒钟可爬过的踏板的数量。在 独占一部梯子过河的情况下,一只速度为??的猴子过河所需的时间为? ?? 秒。如果有 另一只猴子在它前方但速度较慢,则它的行进速度不得不降低。

注:此处一只猴子对另一只猴子的“阻挡”,含义不够清晰,这里用例子解释。

例 1:在某个时刻,猴子??1位于某架梯子的第 1 个踏板上,其速度为 3,猴 子??2位于同一架梯子的第 3 个踏板上,其速度为 1。假如此时??1线程在做行动 决策,在它独自过河的情况下(理想情况),它应该跳到第1 + 3 = 4个踏板上, 但按照 synchronization/lock 的观点,它需要按次序申请第 2、3、4 三个踏板的 “锁”。但是,它观察到自己前方??2的存在,第 3 个踏板目前由??2拥有,故??1 无法按预期跳到第 4 个踏板上,它只能降低速度,以速度 1 跳到第 2 个踏板上。

有同学问:??2也在向前行进,下 1 秒钟??2应该移动到第 4 个踏板上,所以 ??1可以提前做好预判,跳到??2空出的第 3 个踏板上。——这种情况这违反了后 面所提到的不能使用“上帝视角”的原则——猴子只能观察各梯子和各猴子的状态及其变化,但不能得知其他任何猴子所采取的决策策略。所以,??1做决策的时 候,不能假设自己能够获知??2的行动策略。

例 2:假如??1此时在第 2 个踏板上。按照例 1 中的解释,它要申请对第 3、 4、5 条踏板的 lock,但第 3 条踏板已被 lock,故在此时??1的决策只能是“原地 不动”。到了下一次做决策的时候,除非??2已经空出了第 3 条踏板,否则它还是 不能行动。

一个猴子生成一个线程,猴子过河最主要面临的问题,是线程之间竞争的问题。所以用猴子生成线程的时候,我锁住了线程的选择策略,让每一个猴子独立的选择梯子,假如返回时null,用一个do while 循环 等待1s,然后继续选择知道选到梯子为止。

当选出来了梯子,对于每个猴子,选完梯子后,它现在就已经在梯子的一号位置了。执行一个while循环,终止条件是 猴子现在的位置>20了,当猴子开始跳之前,用time1记录时间,str记录猴子选择的梯子名称,猴子id,猴子速度。让线程休眠1s,保证没一步跳一次。

当梯子上只有一个猴子的时候,用time2记录此时的时间,然后日志记录time2-time1作为此猴子已经跑了多少秒,现在猴子的位置是猴子的速度+当前位置。

梯子上的猴子数>1个时候,假如现在这个线程是第一个上梯子的猴子,那啥都不用管,只管往前跑,同时记录时间,记录日志。,假如当前线程不是第一个猴子,则对梯子上的猴子开始遍历,找到与当前线程相等的猴子,然后判断他的速度+位置,是否大于他前一只猴子

的位置,假如大于,就把它的位置设置前一个猴子的位置-1,并且速度与前一个猴子相同,否则,正常自身位置+速度跳就行。

  1   @Override
  2   public void run() {
  3     list1.add(System.currentTimeMillis());
  4     long time = 0;
  5     long time1 = 0;
  6     long time2 = 0;
  7     long time3 = 0;
  8     long time4 = 0;
  9     String str = "";
 10     String str1 = "";
 11     Context con1 = new Context(new Choose1());
 12     Context con2 = new Context(new Choose2());
 13     Context con3 = new Context(new Choose3());
 14     final Monkey threadname = this;
 15
 16     // st.createladder();
 17     synchronized (threadname) {
 18       if(threadname.getid()<=5) {
 19         la = con1.executeStrategy(MonkeyGenerator.l, threadname);
 20       }
 21       else if(threadname.getId()<=10) {
 22         la = con2.executeStrategy(MonkeyGenerator.l, threadname);
 23       }
 24       else {
 25         la = con3.executeStrategy(MonkeyGenerator.l, threadname);
 26       }
 27         if (la == null) {
 28         do {
 29           try {
 30             wait(1);
 31             time1 += 0.1;
 32             final LogRecord lr = new LogRecord(Level.WARNING, "在右岸等待" + time1 + "s");
 33             MonkeyGenerator.log.log(lr);
 34           } catch (final InterruptedException e) {
 35             e.printStackTrace();
 36           }
 37           la = con3.executeStrategy(MonkeyGenerator.l, threadname);
 38         } while (la == null);
 39
 40       }
 41
 42     }
 43     if (la != null) {
 44       while (threadname.getLocation() <= Readfile.h) {
 45         // System.out.println(la.getLaddername()+" "+la.list);
 46         time1 = System.currentTimeMillis();
 47         str = "la:" + la.getLaddername() + " "
 48             + "ID:" + threadname.id + " " + "v:" + threadname.vv + " ";
 49         try {
 50           Thread.sleep(1000);
 51         } catch (final InterruptedException e) {
 52           e.printStackTrace();
 53         }
 54         if ((la.list.size() >= 0) && (la.list.size() <= 1)) {
 55           time2 = System.currentTimeMillis();
 56           final String result = ((time2 - time1) / 1000) + "";
 57           final LogRecord lr = new LogRecord(Level.INFO, "位于第"
 58               + la.getLaddername() + "架梯子的" + threadname.getLocation()
 59               + "位置" + "方向是" + threadname.getDirection() + "已经跑了" + result + "秒");
 60           MonkeyGenerator.log.log(lr);
 61           time += time2 - time1;
 62           // System.out.print("4"+" ");
 63           threadname.setLocation(threadname.getLocation() + threadname.getV());
 64         } else if (la.list.size() > 1) {
 65
 66           if (la.list.get(0).equals(this)) {
 67             time3 = System.currentTimeMillis();
 68             final String result = ((time3 - time1) / 1000) + "";
 69             final LogRecord lr = new LogRecord(Level.INFO, "位于第" + la.getLaddername() + "架梯子的"
 70                 + threadname.getLocation()
 71                 + "位置" + "方向是" + threadname.getDirection() + "已经跑了" + result + "秒");
 72             MonkeyGenerator.log.log(lr);
 73             time += time3 - time1;
 74             // System.out.print("1"+" ");
 75             threadname.setLocation(threadname.getLocation() + threadname.getV());
 76           } else {
 77             for (int i = 1; i < la.list.size(); i++) {
 78               // System.out.println("this:" + this);
 79               // System.out.println("get(0): "+ la.getLaddername()+" "+la.list);
 80               if (la.list.get(i).equals(threadname)) {
 81                 if (((threadname.getLocation() + threadname.getV())
 82                     >= la.list.get(i - 1).getLocation())
 83                     )  {
 84                   // System.out.print("2"+ " ");
 85                   // System.out.println("get(0): "+ la.getLaddername()+" "+la.list);
 86                   time4 = System.currentTimeMillis();
 87                   final String result = ((time4 - time1) / 1000) + "";
 88                   final LogRecord lr = new LogRecord(Level.INFO, "位于第"
 89                       + la.getLaddername() + "架梯子的"
 90                       + threadname.getLocation() + "位置" + "方向是"
 91                       + threadname.getDirection() + "已经跑了" + result + "秒");
 92                   MonkeyGenerator.log.log(lr);
 93                   time += time4 - time1;
 94                   threadname.setLocation(la.list.get(i - 1).getLocation() - 1);
 95                   threadname.setV(la.list.get(i - 1).getV());
 96                 } else {
 97                   // System.out.print("3"+" ");
 98                   time4 = System.currentTimeMillis();
 99                   final String result = ((time4 - time1) / 1000) + "";
100                   final LogRecord lr = new LogRecord(Level.INFO, "位于第"
101                       + la.getLaddername() + "架梯子的"
102                       + threadname.getLocation() + "位置"
103                       + "方向是" + threadname.getDirection() + "已经跑了" + result + "秒");
104                   MonkeyGenerator.log.log(lr);
105                   time += time4 - time1;
106                   threadname.setLocation(threadname.getLocation() + threadname.getV());
107                 }
108               }
109
110             }
111           }
112
113         }
114         // System.out.println(str = "la:" + la.getLaddername()+" "+"ID:"+threadname.ID+"
115         // "+"v:"+threadname.v+" "+" " +threadname.getLocation());
116         str1 = str1 + " " + threadname.getLocation();
117       }
118     }
119
120     MonkeyGenerator.log.info("                                                         ");
121     final LogRecord lr = new LogRecord(Level.INFO, "跑完了"
122         + "一共跑了" + " " + (time / 1000) + " " + "秒");
123     MonkeyGenerator.log.log(lr);
124     MonkeyGenerator.log.info("                                                         ");
125
126     System.out.println(str + " " + str1);
127     s += str + " " + str1 + "\n";
128     if (threadname.location > 20) {
129       for (int i = 0; i < la.list.size(); i++) {
130         if (la.list.get(i) != null) {
131           if (la.list.get(i).equals(threadname)) {
132             la.list.remove(i);
133             // System.out.println("sss");
134             i--;
135           }
136         }
137
138       }
139     }
140     list.add(System.currentTimeMillis());
141     list1.add(System.currentTimeMillis());
142     map.put(threadname, list1);
143
144   }

原文地址:https://www.cnblogs.com/hitszbw/p/9162588.html

时间: 2024-10-06 22:58:11

software construction in Java Lab6的相关文章

HIT Software Construction Lab6引发出来对锁的问题的探究

前言 做完lab5开始做lab6了鸭,哈工大计算机学院的学生永不停歇.在做lab6的时候,我在想移动猴子是锁一整个ladder(ADT)还是只锁一个ladder的一个域Monkey数组呢?这两个好像差不多,然后就开始思考锁一个对象和锁其中一个域有什么区别?如果锁了对象对于方法调用有什么影响?回想起上课老师讲的一个类的synchronized方法之间是mutual excluded我就不太明白这到底是怎么回事 我问了隔壁大佬如果锁了对象,类似于: synchronized (object) { .

Software Construction Series(2)

Collections.unmodifiable*()与Rep Exposure JDK在collections接口中提供了一类静态函数:collections.unmodifiable*(),其中*匹配Collections的子类. 如图: 简而言之:这类函数返回一个相应对象的不可更改的Copy. 问题在于不可更改性到那种程度: 1.相当于final?(即reference不可变) 2.相当于imutable?(即集合本身内容不可变,其中元素仍可变) 3.相当于can't do anythin

HIT Software Construction Lab 3

? 2019年春季学期 计算机学院<软件构造>课程 Lab 3实验报告 姓名 刘帅 学号 1170500804 班号 1703008 电子邮件 [email protected] 手机号码 目录 1 实验目标概述··· 1 2 实验环境配置··· 1 3 实验过程··· 1 3.1 待开发的三个应用场景··· 1 3.2 基于语法的图数据输入··· 2 3.3 面向复用的设计:CircularOrbit· 2 3.4 面向复用的设计:Track· 4 3.5 面向复用的设计:L· 4 3.6

370 门免费编程与计算机科学在线课程

简评:这篇文章为大家整理出 370 门精选的免费高质量编程计算机科学类的课程(涵盖程序语言.人工智能.深度学习与机器学习等热门话题).这370 门课程是从 Class Central数据库里面的 7000 门课程挑选出来的,每个课程的 Rating(评价)也是由该网站上获取下来的平均值. 370 门课程里面根据难易程度被分为: 入门 中级 进阶 所收录的大部分教程都已经更新完毕了,你可以按照自己的节奏(Self Paced)随时观看学习,有小部分教程还在持续更新至中,当然了,它们全都是免费的!

浅谈Java中的数据类型

主要内容来自MIT6.031 Software Construction课程及HIT 软件构造课程. Java的数据类型有两种,分为基本数据类型(primitive types)及对象数据类型(object types).例如int ,float,boolean等类型就是基本数据类型,而String ,Integer ,BigInteger等类型就是对象数据类型. 下面介绍一下这两点的异同: 基本数据类型都是不可变的(Immutable),而对象数据类型一些是可变的(mutable),一些则不是

学了编译原理能否用 Java 写一个编译器或解释器?

16 个回答 默认排序? RednaxelaFX JavaScript.编译原理.编程 等 7 个话题的优秀回答者 282 人赞同了该回答 能.我一开始学编译原理的时候就是用Java写了好多小编译器和解释器.其实用什么语言来实现编译器并不是最重要的部分(虽然Java也不是实现编译器最方便的语言),最初用啥语言都可以. 我在大学的时候,我们的软件工程和计算机科学的编译原理课的作业好像都是可以用Java来写的.反正我印象中我给这两门课写的作业都是用的Java. ===================

Java学习网站汇总【备忘】

Java学习网站http://www.javaxxz.com Java学习者论坛,资源非常多,适合初学者. http://www-900.ibm.com/developerWorks/cn/java/index.shtml IBM的JAVA专题——永远的蓝色巨人 http://www.huihoo.com 灰狐动力——Enterprise Open Source http://www.jdon.com J道——JAVA和J2EE解决之道 http://www.chinaunix.net Chin

Java核心 --- 枚举

Java核心 --- 枚举 枚举把显示的变量与逻辑的数字绑定在一起在编译的时候,就会发现数据不合法也起到了使程序更加易读,规范代码的作用 一.用普通类的方式实现枚举 新建一个终态类Season,把构造方法设为私有,因为枚举值不能随意增加因为不能new出这个类的对象,所以需要定义成员变量,把new写在类的内部这样,就可以在类的外部通过访问类的静态成员变量的方式访问到枚举值通过这样的方式,只能在类的外部使用在枚举类的内部定义的枚举值 类Season里面是可以有方法的,我们设置地球又公转了四分之一方法

(转) WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

今天要用Jmeter测试服务器性能,发现GUI界面总是有warning提示: 今天要用Jmeter测试服务器性能,发现GUI界面总是有warning提示: WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5. 在网上搜了搜,发现是Jmeter需要写注册表. 解决办法如下