猴子

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   }

 

posted @ 2018-06-10 11:32  hitszbw  阅读(328)  评论(0编辑  收藏  举报