1. 程式人生 > >software construction in Java Lab6

software construction in Java Lab6

多少秒 create .info 上帝 屬性 問題 TP fin rect

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   }

software construction in Java Lab6