




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、教師對學(xué)生的項目評分進程的同步與互斥一、 課題內(nèi)容和要求1、課題內(nèi)容:在一個班上有S個學(xué)生。每個學(xué)生都要做一個項目,每一個項目由K個老師一起評分??偣灿蠱個老師。每個老師最多給N個項目評分。其中,S*KD。每一個學(xué)生的項目由K個老師共同來檢查。在T分鐘的時間段內(nèi),學(xué)生可以在任何時間進入教室(random),除了在最后的D分鐘內(nèi)。所有的老師一直保持工作狀態(tài)直到他檢查完N個項目或者是T分鐘過去后。T分鐘過去后,所有的老師和同學(xué)都必須離開教室。另外,在T分鐘結(jié)束前的D分鐘內(nèi)(即在最后的D分鐘內(nèi)),如果有任何老師或者是學(xué)生都處在沒有任務(wù)的狀態(tài)下,都必須離開教室,因為已經(jīng)沒有時間讓他完成任務(wù)了(因為一個
2、項目檢查的時間是整整D分鐘)。當(dāng)一個學(xué)生進入教室后,他立即開始找K個沒有任務(wù)的老師(一次找一個老師,假如沒有空閑的老師,則等到有老師為止),找齊K個老師之后給老師檢查,然后離開教室。剛開始每一個老師都是處于空閑狀態(tài)直到他被學(xué)生找到,被學(xué)生找到后只能等待,直到學(xué)生找齊K個老師(在等待學(xué)生找其他老師的時間里,他是不能接受其他同學(xué)檢查作業(yè)的請求的),當(dāng)學(xué)生找齊K個老師后,老師們執(zhí)行完檢查任務(wù),然后重新變成空閑狀態(tài)。每個老師在總共檢查了N個學(xué)生的作業(yè)后,離開教室。2、基本要求:用一個程序來模擬上面描述的作業(yè)檢查過程。每一個學(xué)生和每一個老師應(yīng)該用不同的線程來完成??梢赃x用C、C+和Java作為開發(fā)語言,
3、但是考慮到專業(yè)課程設(shè)計I的實驗大綱,請盡可能使用Java語言。3、提高要求:(1) 考慮到跨平臺的特性,請盡量使用posix線程標(biāo)準(zhǔn)(采用該標(biāo)準(zhǔn)有額外的加分);(2) 實現(xiàn)良好的圖形用戶界面;(3) 在程序演示過程中能清晰的展示多個學(xué)生線程和多個老師線程的同步和互斥流程。二、需求和思路分析1、Java線程由于Java具有平臺無關(guān)性(“Write once,run anywhere”)和內(nèi)置對多線程的支持(java.lang包中的Thread類),所以本次課程設(shè)計考慮采用Java語言編寫線程,下面簡單介紹一下可能用到的一些方法。(1)start()線程調(diào)用該方法將啟動線程,使之從新建狀態(tài)進入就緒
4、隊列排隊,一旦輪到它來享用CPU資源時,就可以脫離創(chuàng)建它的主線程開始自己的生命周期了。(2)run()Thread類的run()方法與Runnable接口中的run()方法的功能和作用相同,都用來定義線程對象被調(diào)度之后所執(zhí)行的操作,都是系統(tǒng)自動調(diào)用而用戶程序不得引用的方法。調(diào)用start()方法(從父類繼承的方法)通知JVM,等待JVM將CPU使用權(quán)切換給該線程。當(dāng)JVM將CPU使用權(quán)切換給線程時,如果線程是Thread的子類創(chuàng)建的,該類中的run()方法沒有具體內(nèi)容,程序要在Thread類的子類中重寫run()方法來覆蓋父類的run()方法,run()方法規(guī)定了該線程的具體使命。當(dāng)run()
5、方法執(zhí)行完畢,線程就變成死亡狀態(tài)。在線程沒有結(jié)束run()方法之前,不要再調(diào)用start()方法,否則將發(fā)生IllegalThreadStateException異常。(3)sleep(int millsecond)線程使用CPU資源期間,執(zhí)行了sleep(int millsecond)方法,使當(dāng)前線程進入休眠狀態(tài)。sleep(int millsecond)方法是Thread類中的一個類方法,線程一旦執(zhí)行了sleep(int millsecond)方法,就立刻讓出CPU的使用權(quán),使當(dāng)前線程處于中斷狀態(tài)。經(jīng)過參數(shù)millsecond指定的毫秒數(shù)之后,該線程就重新進到線程隊列中排隊等待CPU資源,
6、以便從中斷處繼續(xù)執(zhí)行。如果線程在休眠時被打斷,JVM就拋出InterruptedException異常。因此必須在try-catch語句塊中調(diào)用sleep(int millsecond)方法。(4)currentThread()currentThread()方法是Thread類中的類方法,可以用類名調(diào)用,該方法返回當(dāng)前正在使用CPU資源的線程。(5)線程的同步當(dāng)使用多個線程來訪問同一個數(shù)據(jù)時,非常容易出現(xiàn)線程安全問題(比如多個線程都在操作同一數(shù)據(jù)導(dǎo)致數(shù)據(jù)不一致),所以我們用同步機制來解決這些問題。實現(xiàn)同步機制有兩個方法:a)同步代碼塊:synchronized(同一個數(shù)據(jù))同一個數(shù)據(jù):就是N條
7、線程同時訪問一個數(shù)據(jù)。b)同步方法:public synchronized 數(shù)據(jù)返回類型 方法名()使用 synchronized 來修飾某個方法,則該方法稱為同步方法。對于同步方法而言,無需顯示指定同步監(jiān)視器,同步方法的同步監(jiān)視器是 this 也就是調(diào)用該同步方法的對象的本身當(dāng)使用synchronized 來修飾某個共享資源時(分同步代碼塊和同步方法兩種情況),當(dāng)某個線程獲得共享資源的鎖后就可以執(zhí)行相應(yīng)的代碼段,直到該線程運行完該代碼段后才釋放對該共享資源的鎖,讓其他線程有機會執(zhí)行對該共享資源的修改。當(dāng)某個線程占有某個共享資源的鎖時,如果另外一個線程也想獲得這把鎖運行就需要使用wait()
8、和notify()/notifyAll()方法來進行線程通訊了(6)wait()、notify()、notifyAll()wait()、notify()、notifyAll()都是Object類中的final方法,被所有的類繼承,且不允許重寫。wait()方法導(dǎo)致當(dāng)前線程等待,直到其他線程調(diào)用同步監(jiān)視器的notify()方法或notifyAll()方法來喚醒該線程。notify()方法喚醒在同步監(jiān)視器上等待的單個線程,如果所有線程都在同步監(jiān)視器上等待,則會選擇喚醒其中一個線程,選擇是任意性的,只有當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,也就是使用wait方法后,才可以執(zhí)行被喚醒的線程。notify
9、All()方法喚醒在同步監(jiān)視器上等待的所有的線程。只用當(dāng)前線程放棄對該同步監(jiān)視器的鎖定后,才可以執(zhí)行被喚醒的線程。(7)創(chuàng)建線程有兩種方法,一是創(chuàng)建Thread子類以繼承Thread類,但Java不支持多繼承,靈活性不夠好。二是用Thread類直接創(chuàng)建線程對象,使用構(gòu)造方法Thread(Runnable target)實現(xiàn)Runnable接口對于使用同一目標(biāo)對象的線程,目標(biāo)對象的成員變量就是這些線程共享的數(shù)據(jù)單元;另外,創(chuàng)建目標(biāo)對象類在必要時還可以是某個特定類的子類。正因此,使用Runnable接口比使用Thread的子類更具有靈活性。所以,本次課程設(shè)計考慮采用實現(xiàn)Runnable接口的方法來
10、創(chuàng)建老師和學(xué)生線程。2、主線程模塊產(chǎn)生學(xué)生進入的隨機時間;全部老師進入教室;學(xué)生進入教室;等待;時間T到達,退出程序;3、學(xué)生線程模塊學(xué)生線程執(zhí)行下面的步驟:選擇一個進入的時間(random()%T) ;進入教室;選擇K個空閑的老師,若找不齊,則等待;找齊后,做D分鐘的檢查;檢查完畢離開教室。4、老師線程模塊老師線程執(zhí)行下面的步驟:在教室中空閑;直到被一個學(xué)生選擇后等待(所有K個老師聚集);等待結(jié)束項目檢查開始;做D分鐘的項目檢查,返回(1);N次檢查完畢或者T分鐘時間到,離開教室。5、注意事項:在剩余時間小于D時,一個已創(chuàng)建的學(xué)生線程只能執(zhí)行第(5)步,不能再創(chuàng)建新的學(xué)生線程;在剩余時間小于
11、D時,一個老師進程只能在執(zhí)行(3)(4)步或者直接執(zhí)行第(5)步;對于所有合理的S, M, K, N, T, D數(shù)值(這些數(shù)必須都是正整數(shù)并且滿足條件:S*KD),程序都能夠運行成功;程序?qū)λ械臅r間安排策略都必須運行成功。例如不管線程的相對速度,例如要把握好sleep的毫秒數(shù);在每一個線程的生命周期內(nèi),每一步都要有一個合理的說明信息,來表明這個線程中包括哪個老師,哪個學(xué)生,進行到什么程度了;要特別注意防范死鎖問題的發(fā)生。三、概要設(shè)計仔細分析課題,可以分為以下幾個模塊實現(xiàn):1、主線程通過人機對話獲得所需要的學(xué)生人數(shù)S,老師人數(shù)M,學(xué)生需要接受檢查的老師數(shù)K,老師最多檢查學(xué)生數(shù)N,總時間 T,學(xué)
12、生接受檢查所需時間D。調(diào)用隨機函數(shù)產(chǎn)生學(xué)生線程產(chǎn)生的時間,接著創(chuàng)建ProjectCheck類實現(xiàn)Runnable接口產(chǎn)生老師線程,等老師線程全部產(chǎn)生,一旦學(xué)生線程產(chǎn)生時間一到立即產(chǎn)生學(xué)生線程,等待時間T到,結(jié)束所有未結(jié)束的學(xué)生和老師線程,退出程序。2、ProjectCheck類(1)成員變量:int S, M, K, N, T, D; /學(xué)生人數(shù)S,老師人數(shù)M,學(xué)生需要接受檢查的老師數(shù)K,老師最多檢查學(xué)生數(shù)N,總時間 T,學(xué)生接受檢查所需時間Dint countCurrentTeacher;/當(dāng)前處于空閑狀態(tài)的老師數(shù)目static long timeStart;/程序開始時間boolean t
13、eacherBusy;/老師當(dāng)前忙閑狀態(tài)int teacherCountOfCheckedProject;/當(dāng)前已經(jīng)檢查過的項目數(shù)目 Thread teacher; /老師線程Thread student; /學(xué)生線程final static int EMPTY = 0; /狀態(tài)“空”,沒人進入或離開教室final static int COMING = 1; /狀態(tài)“進入”,有人正在進入教室final static int LEAVING = 2; /狀態(tài)“離開”,有人正在離開教室int state; /教室當(dāng)前狀態(tài)(2)成員函數(shù):public static int gettime();/獲
14、取相對于timeStart的當(dāng)前時間,以ms為單位public ProjectCheck(int S, int M, int K, int N, int T, int D, long timeStart); /構(gòu)造函數(shù),初始化一些成員變量public void run(); /重寫接口中的方法/保證同一時刻只有一人進入或者離開public synchronized void comeLock(); /有人進入“鎖”public synchronized void leaveLock(); /有人離開“鎖”public synchronized void comeUnlock(); /有人進入“
15、解鎖”public synchronized void leaveUnlock(); /有人離開“解鎖”public void startCheck(int id); /在run()方法中調(diào)用此方法,針對不同的老師線程、學(xué)生線程開始檢查(3)老師線程老師線程的流程圖如下圖所示。對老師進入上鎖、解鎖保證同一時刻只有一名老師進入,打印老師進入信息表明老師已進入教室,教室中處于空閑狀態(tài)的老師人數(shù)加1。接著利用while循環(huán)判斷結(jié)束時間T是否到達和老師檢查次數(shù)是否到達N,兩個條件都不滿足則繼續(xù)循環(huán)判斷那兩個條件,老師即處于等待狀態(tài),否則如果老師檢查學(xué)生的次數(shù)到達N,說明老師已完成規(guī)定的檢查任務(wù),已經(jīng)離
16、開,如果時間T到達,說明所有線程都要結(jié)束,所以這兩種情況都要跳出循環(huán),準(zhǔn)備離開。最后對老師離開上鎖、解鎖保證同一時刻只有一名老師離開,打印老師離開信息,教室中處于空閑狀態(tài)的老師人數(shù)減1。老師線程結(jié)束。開始調(diào)用comeLock()方法上鎖教室中空閑老師人數(shù)countCurrentTeacher加1打印老師進入信息調(diào)用comeUnlock()方法解鎖判斷時間T是否到達或N次檢查已完成教室中空閑老師人數(shù)countCurrentTeacher減1打印老師離開信息調(diào)用leaveUnlock()方法解鎖調(diào)用leaveLock()方法上鎖結(jié)束YesNoYesYesNoNo(4)學(xué)生線程判斷當(dāng)前時刻是否大于T
17、-D,若大于則說明剩余時間不夠老師檢查,學(xué)生立即離開即學(xué)生線程結(jié)束,否則對學(xué)生進入上鎖、解鎖保證同一時刻只有一名學(xué)生進入,打印學(xué)生進入信息表明學(xué)生已經(jīng)進入教室。接著在尋找K個老師檢查之前,先利用while循環(huán)判斷目前教室中處于空閑狀態(tài)的老師人數(shù)是否小于K,若小于表明目前該學(xué)生無法找到K個老師為他檢查,則繼續(xù)判斷該條件,學(xué)生即處于等待狀態(tài),否則立即把教室中處于空閑狀態(tài)的老師人數(shù)減去K,跳出循環(huán),尋找K個老師檢查。學(xué)生等待過程中,若剩余時間不足D,則學(xué)生立即離開即學(xué)生線程結(jié)束。尋找K個老師通過for循環(huán)K次,每次循環(huán)調(diào)用Random類的nextInt(M)方法尋找老師,利用while循環(huán)判斷老師已
18、檢查次數(shù)是否到達N和老師是否正在檢查別人即狀態(tài)是否處于忙,兩個條件只要有一個被滿足,再調(diào)用Random類的nextInt(M)方法尋找老師,否則就立即修改老師的忙閑狀態(tài),保存老師序號。找齊K個老師后,開始檢查,調(diào)用Thread類的類方法sleep()阻塞時間D。等檢查完畢,利用K次for循環(huán),將這K個老師的忙閑狀態(tài)置閑,并把這些老師的檢查次數(shù)加1,教室中處于空閑狀態(tài)的老師人數(shù)加1。最后對學(xué)生離開上鎖、解鎖保證同一時刻只有一名學(xué)生離開,打印學(xué)生離開信息。學(xué)生線程結(jié)束。學(xué)生線程的流程圖如下圖所示。開始判斷時間T-D是否到達調(diào)用comeLock()方法上鎖打印學(xué)生進入信息調(diào)用comeUnlock()
19、方法解鎖判斷空閑老師數(shù)countCurrentTeacher KcountCurrentTeacher=countCurrentTeacher-KiK調(diào)用Random類的nextInt方法隨機找空閑老師判斷該老師狀態(tài)是否處于忙或?qū)⒊蓪W(xué)生次數(shù)已達N將老師忙閑狀態(tài)置忙保存老師序號打印老師開始檢查學(xué)生的信息i+調(diào)用Thread類方法sleep(),堵塞時間DiK取出老師序號將老師的忙閑狀態(tài)置閑老師檢查次數(shù)加1打印老師結(jié)束檢查學(xué)生的信息countCurrentTeacher+i+調(diào)用leaveLock()上鎖打印學(xué)生離開信息調(diào)用leaveUnlock()解鎖結(jié)束打印學(xué)生離開信息YesYesNoNoNo
20、YesYesYesYesNoYesNoNoNo四、詳細設(shè)計源程序代碼如下:創(chuàng)建名為projectCheck的工程文件,創(chuàng)建名為projectCheck.java和Main.java的類文件。projectCheck.java:package com.sand;import java.util.Scanner;import java.util.Random;import java.awt.*;import java.lang.InterruptedException;public class ProjectCheck implements Runnable int S, M, K, N, T,
21、D; /學(xué)生人數(shù)S,老師人數(shù)M,學(xué)生需要接受檢查的老師數(shù)K,老師最多檢查學(xué)生數(shù)N,總時間 T,學(xué)生接受檢查所需時間D int countCurrentTeacher;/當(dāng)前處于空閑狀態(tài)的老師數(shù)目 static long timeStart;/程序開始時間 boolean teacherBusy;/老師當(dāng)前忙閑狀態(tài) int teacherCountOfCheckedProject;/當(dāng)前已經(jīng)檢查過的項目數(shù)目 Thread teacher; /老師線程 Thread student; /學(xué)生線程 final static int EMPTY = 0; /狀態(tài)“空”,沒人進入或離開教室 final
22、static int COMING = 1; /狀態(tài)“進入”,有人正在進入教室 final static int LEAVING = 2; /狀態(tài)“離開”,有人正在離開教室 int state; /教室當(dāng)前狀態(tài) public ProjectCheck(int S, int M, int K, int N, int T, int D, long timeStart) /構(gòu)造函數(shù),初始化一些成員變量 this.S = S; this.M = M; this.K = K; this.N = N; this.T = T; this.D = D; this.timeStart = timeStart;
23、state = EMPTY; countCurrentTeacher = 0; /初始化當(dāng)前處于空閑狀態(tài)的老師數(shù)目為0 int i; teacherBusy = new booleanM; for (i = 0; i M; i+) teacherBusyi = false; /初始化老師的忙閑狀態(tài)為空閑 teacherCountOfCheckedProject = new intM; for (i = 0; i M; i+) teacherCountOfCheckedProjecti = 0; /初始化老師的檢查次數(shù)為0 teacher = new ThreadM; /創(chuàng)建線程名為teache
24、ri的老師線程 for (i = 0; i M; i+) teacheri = new Thread(this,teacher + i); student = new ThreadS; /創(chuàng)建線程名為studenti的學(xué)生線程 for (i = 0; i S; i+) studenti = new Thread(this,student + i); public static int gettime() /獲取相對于timeStart的當(dāng)前時間,以ms為單位 long timeCurrent; int duration; timeCurrent = System.currentTimeMill
25、is(); duration = (int)(timeCurrent - timeStart); return duration; public void run() /重寫接口中的方法 int i; int max; while(true) for (i = 0; i M; i+) if (Thread.currentThread().getName().equals(teacher + i) startCheck(i); return ; for (i = 0; i S; i+) if (Thread.currentThread().getName().equals(student + i
26、) startCheck(i); return ; /保證同一時刻只有一人進入或者離開 public synchronized void comeLock() /有人進入“鎖” if(state = EMPTY) state = COMING; else if(state = COMING) else if(state = LEAVING) try wait(); catch(InterruptedException e) state = COMING; public synchronized void leaveLock() /有人離開“鎖” if(state = EMPTY) state
27、= LEAVING; else if(state = LEAVING) else if(state = COMING) try wait(); catch(InterruptedException e) state = LEAVING; public synchronized void comeUnlock() /有人進入“解鎖” state = EMPTY; notify(); public synchronized void leaveUnlock() /有人離開“解鎖” state = EMPTY; notify(); public void startCheck(int id) /針對
28、不同的老師線程、學(xué)生線程開始檢查 if (Thread.currentThread().getName().equals(teacher + id)/老師線程所要完成的操作 comeLock(); /使同一時刻只有一人進入或離開教室 countCurrentTeacher+; /教室中空閑老師人數(shù)加1 System.out.println(gettime() + ms:+Thread.currentThread().getName() + enters classroom); /打印老師進入信息 comeUnlock(); /判斷當(dāng)前時間是否小于T并且老師檢查次數(shù)是否小于N,若兩者都滿足,則繼
29、續(xù)等待,否則跳出循環(huán)。 while (teacherCountOfCheckedProjectid N & (int)(gettime() T - D) /剩余時間是否小于D leaveLock(); /是,則學(xué)生離開 System.out.println(gettime() + ms:+ Thread.currentThread().getName() + does not need to enter classroom (time is not enough);/打印學(xué)生離開信息,時間不夠 leaveUnlock(); return ; /結(jié)束學(xué)生線程 else comeLock(); /
30、不是,學(xué)生進入教室 System.out.println(gettime() + ms:+ Thread.currentThread().getName() + enters classroom);/打印學(xué)生進入信息 comeUnlock(); synchronized(this) while (countCurrentTeacher T - D) /等待過程中,若剩余時間小于D,則結(jié)束等待,退出教室 comeLock(); System.out.println(gettime() + ms:+ Thread.currentThread().getName() + exits classroo
31、m (time is not enough); comeUnlock(); return ; /目前教室中能找齊K個空閑的老師,立即將處于空閑狀態(tài)的老師人數(shù)減去K,防止死鎖 countCurrentTeacher = countCurrentTeacher - K; int studentCheckingQueue;/記錄檢查id號學(xué)生的老師號 studentCheckingQueue = new intK; int studentIndexOfNextTeacher;/記錄待查找老師坐標(biāo) studentIndexOfNextTeacher = 0; Random random=new Ran
32、dom(); for (int i = 0; i = N表明老師已完成任務(wù),已離開,teacherBusystudentIndexOfNextTeacher表明老師正在忙,為別人檢查,繼續(xù)尋找 while ( teacherBusystudentIndexOfNextTeacher | teacherCountOfCheckedProjectstudentIndexOfNextTeacher = N) studentIndexOfNextTeacher = random.nextInt(M); teacherBusystudentIndexOfNextTeacher = true; /找到老師
33、,修改其忙閑狀態(tài) studentCheckingQueuei = studentIndexOfNextTeacher;/保存老師序號 System.out.println(gettime()+ms:teacher+studentIndexOfNextTeacher+ grabbed by student+id+ (job+teacherCountOfCheckedProjectstudentIndexOfNextTeacher+); System.out.println(gettime() + ms:+ Thread.currentThread().getName() + starts che
34、ck); try /檢查學(xué)生 Thread.sleep(D); catch (InterruptedException e) for (int i = 0; i K; i+) /檢查完畢,釋放老師 /以下兩句執(zhí)行順序問題,若先+可能出現(xiàn)老師還沒打印輸出finished with student的消息,而已經(jīng)grabbed by student System.out.println(gettime() + ms:teacher + studentCheckingQueuei + finished with student + id + (job + teacherCountOfCheckedPr
35、ojectstudentCheckingQueuei +); teacherBusystudentCheckingQueuei = false; /將老師忙閑狀態(tài)置閑 teacherCountOfCheckedProjectstudentCheckingQueuei +; /老師檢查次數(shù)加1 countCurrentTeacher +; /教室中處于空閑狀態(tài)的老師人數(shù)加1 leaveLock(); /學(xué)生離開教室System.out.println(gettime() + ms:+ Thread.currentThread().getName() + ends check); System.o
36、ut.println(gettime() + ms:+ Thread.currentThread().getName() + exits classroom (finished); leaveUnlock(); Main.java:package com.sand;import java.util.Random;import java.util.Scanner;import java.lang.Thread;public class Main public static void main(String args) Scanner scan = new Scanner(System.in);
37、/獲取S、M、K、N、T、D的值 int S,M,K,N,T,D; System.out.println(please input students number (S):); S=scan.nextInt(); System.out.println(please input teachers number (M):); M=scan.nextInt(); System.out.println(please input required teachers number by every student(K):); K=scan.nextInt(); System.out.println(ple
38、ase input checked projects number at most (N):); N=scan.nextInt(); System.out.println(please input total time (T):); T=scan.nextInt(); System.out.println(please input checked time (D):); D=scan.nextInt(); System.out.println(S=+S+,M=+M+,K=+K+,N=+N+,T=+T+ms,D=+D+ms); Random random=new Random(); int en
39、terTime=new intS; /enterTime數(shù)組保存學(xué)生進入的隨機時間 System.out.println(students enter time:); for(int i=0;iS;i+) enterTimei = random.nextInt(T - D);/產(chǎn)生隨機進入的時間,保存于enterTime數(shù)組中 System.out.print(enterTimei+ms ); System.out.println(); int p; for(int i=0;iS;i+) /將時間從小到大排列,以便學(xué)生依次進入 for(int j=i+1;jS;j+) if(enterTime
40、jenterTimei)p=enterTimej;enterTimej=enterTimei;enterTimei=p; long timeStart; timeStart=System.currentTimeMillis(); ProjectCheck projectCheck; projectCheck=new ProjectCheck(S,M,K,N,T,D,timeStart); for(int i=0;iM;i+) /啟動老師線程 projectCheck.teacheri.start(); for(int i=0;iS;i+) /根據(jù)enterTime數(shù)組依次啟動所有學(xué)生線程 wh
41、ile(projectCheck.gettime()enterTimei); projectCheck.studenti.start(); while(projectCheck.gettime()=T); /等待時間T到達 五、測試數(shù)據(jù)及其結(jié)果分析在NetBeans 6.9.1中打開工程文件,生成主項目,運行主項目。根據(jù)提示輸入學(xué)生人數(shù)S,老師人數(shù)M,學(xué)生需要接受檢查的老師數(shù)K,老師最多檢查學(xué)生數(shù)N,總時間 T,學(xué)生接受檢查所需時間D。具體運行情況如下圖所示:5ms開始,3個老師陸續(xù)進入教室:747ms,學(xué)生0進入教室,找到老師0、1,開始檢查:1165ms,老師0、1檢查完學(xué)生0,學(xué)生0離開
42、教室:1385ms,學(xué)生1進入教室,找到老師0、2,開始檢查:8350ms,學(xué)生2進入教室,找不齊2個空閑的老師,故等待:1799ms,老師0、2檢查完學(xué)生1:1830ms,學(xué)生2找到老師0、2,開始檢查:1839ms,學(xué)生1離開教室:1987ms,學(xué)生3進入教室,找不齊2個空閑的老師,故等待:2257ms,老師0、2檢查完學(xué)生2:2281ms,學(xué)生3找到老師0、1,開始檢查:2298ms,學(xué)生2離開教室:2573ms,學(xué)生4進入教室,找不齊2個空閑的老師,故等待: 2601ms,因為剩余時間不夠檢查,故學(xué)生4離開教室:2709ms,老師0、1檢查完學(xué)生3:2709ms,老師0因為檢查次數(shù)已滿
43、,離開教室:2710ms,學(xué)生3離開教室:3000ms,總時間到達,老師1、2離開教室:六、調(diào)試過程中的問題1、在主函數(shù)的調(diào)試中發(fā)現(xiàn)隨機產(chǎn)生學(xué)生線程的時間有點問題,由于學(xué)生線程是依次產(chǎn)生的,如果學(xué)生線程開始的隨機時間小于當(dāng)前時刻,那么會導(dǎo)致學(xué)生線程根本沒有開始,以致于把后面的學(xué)生線程都堵塞了。所以在這里通過對產(chǎn)生的隨機時間從小到大排列,這樣就可以避免這種問題。2、老師進入教室存在同步問題。如果兩個老師同時進入教室,那么教室中空閑得老師人數(shù)會同時加1而不是加2,這樣就有可能發(fā)生同步問題。經(jīng)過仔細分析,可以通過synchronized關(guān)鍵字來定義同步方法,并使用wait()、notify()方法定
44、義進入鎖和離開鎖來解決同步問題。調(diào)用自定義的comeLock()方法對老師進入教室上鎖,一旦上鎖,別的老師就不可能進入教室,而是處于等待中,直至調(diào)用自定義的comeUnlock()方法解鎖方能進入,這樣就解決了老師與老師之間的同步問題。3、在學(xué)生線程中最大的問題是死鎖的發(fā)生。如果兩個學(xué)生先后進入教室,分別取尋找K個老師,而此時教室中空閑的老師已不足2*K,兩人都無法滿足,相互占有對方所需要的資源而陷入僵局,這樣就會有可能產(chǎn)生死鎖。經(jīng)過思考,可以通過循環(huán)判斷目前教室中空閑的老師人數(shù)是否小于K,若小于,說明學(xué)生進入教室后無法找齊K個老師,則繼續(xù)判斷這個條件,直至目前教室中空閑的老師人數(shù)大于等于K,
45、則說明學(xué)生進入教室后能找齊K個老師,立即將目前教室中空閑的老師人數(shù)減去K,相當(dāng)于提前占用K個老師,這樣下一個進來的學(xué)生就會根據(jù)前一個學(xué)生已經(jīng)占用了K個老師的情況進行判斷,這樣就有效的防止了死鎖的發(fā)生。4、剛開始時,我是把存儲檢查某學(xué)生的M個老師序號的studentCheckingQueue數(shù)組聲明為projectCheck.java中的共享變量,結(jié)果在運行時某些情況下會發(fā)生錯誤。例如在student0找到teacher0、teacher1檢查項目期間,又發(fā)生student1找到teacher2、teacher3檢查項目,那么studentCheckingQueue數(shù)組最初存儲的0,1就會被后來的2,3覆蓋,從而導(dǎo)致錯誤。所以要在student線程中聲明studentCheckingQueue數(shù)組變量,以便每一個student線程都有自己的一段空間存儲老師序號。七、專業(yè)課程設(shè)計總結(jié)初學(xué)Java語言時,只是簡單的了解了它的一些基本概念,例如類與對象、繼承與多態(tài)、平臺無關(guān)性
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 內(nèi)控制度合同范例
- 會議診斷費用合同范例
- 企業(yè)合同范例英文
- 2手汽車購買合同范例
- 321借款合同范例
- 道路翻新施工方案范本
- 家國情懷素養(yǎng)在高中歷史教學(xué)中的培養(yǎng)研究
- 人工水塔拆除施工方案
- 創(chuàng)業(yè)股權(quán)分配合同范例
- 農(nóng)村蔬菜出租合同范本
- 檢驗員培訓(xùn)資料-
- 房屋市政工程施工現(xiàn)場安全風(fēng)險分級管控與防范措施清單
- 第三方工程評估體系檢查表
- 唐僧團隊之如何打造團隊
- 畢業(yè)設(shè)計外文文獻-Spring Boot
- 六年級下冊《生命.生態(tài).安全》全冊教案(表格式)
- DB32/T 4444-2023 單位消防安全管理規(guī)范-高清版
- 《讓孩子成才的秘密》寂靜法師
- 水下作業(yè)工程監(jiān)理實施細則(工程通用版范本)
- 小學(xué)科學(xué)教育探究一研討教學(xué)法
- GB 14930.1-2022食品安全國家標(biāo)準(zhǔn)洗滌劑
評論
0/150
提交評論