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 }
software construction in Java Lab6