1. 本周學習總結
2. 書面作業
1. 源代碼閱讀:多線程程序BounceThread
1.1 BallRunnable類有什么用?為什么代碼中需要調用Thread.sleep進行休眠?
BallRunnable類實現Runnable接口,支持多線程;調用Thread.sleep進行休眠則在規定時間內不參與參與到CPU競爭,讓線程休眠就可以看到小球的運動軌跡,如果時間為0即Thread.Sleep(0),就觸發操作系統立刻重新進行一次CPU競爭就看不見軌跡。
1.2 Ball.java只做了兩件事,這兩件事分別是什么?BallComponent對象是干什么的?其內部的ArrayList有什么用?程序運行過程中,生成了幾個BallComponent對象?該程序使用了多線程技術,每個小球是分別在不同的線程中進行繪制嗎?
- 實現小球的移動方法;獲得小球的坐標和大小
- BallComponent對象的作用是添加小球和畫出小球
- ArrayList用于存放小球
- 運行中生成了一個BallComponent對象
是的每個小球是分別在不同的線程中進行繪制
2. 實驗總結:題集(多線程)
2.1 題目:6-1(Thread)、6-3(Runnable-匿名內部類)。回答:a)通過定義Runnable接口的實現類來實現多線程,比繼承自Thread類實現多線程有何好處?b) 6-1,6-3,6-11實驗總結。
定義Runniable接口比繼承Thread類實現多線程的好處:- 適合多個相同代碼的線程去處理同一個資源的情況
- 可以避免由于java的單繼承特性帶來的局限
增強了程序的健壯性,代碼能夠被多個線程共享,代碼與數據時獨立的
6-1實驗總結:
創建MyThread類對象時指定循環次數n,再創建一個輸出從0到n-1的整數的任務即可。
6-3實驗總結:
創建代表任務的Runnable實現類的對象,在任務里面寫要求的三行輸出。
6-11實驗總結:
這個題與6-1相似,就是要多實現一個Runnable接口。
2.2 使用Lambda表達式改寫6-3
改寫如下:
Thread t1 new Thread (( ) - >{System.out.println(mainThreadName);System.out.println(Thread.currentThread().getName());System.out.println(Arrays.toString(getClass().getInterfaces()));});
2.3 題目:6-2(Runnable與停止線程)。回答:a)需要怎樣才能正確地停止一個運行中的線程?b)6-2實驗總結。
a)不能使用stop()!!!stop()方法已經被廢棄;可以使用共享變量的方式,共享變量可以被多個執行相同任務的線程用來作為是否中斷的信號,通知中斷線程的執行;也可以使用interrupt方法終止線程,這種方法用于線程阻塞時終止線程。
b)public void stopMe();和public void sendWord(String word)方法就編寫語句flag = true;
和this.word = word;
就可以實現,主要是run()方法,對word包含alien按格式進行輸出,要注意加入while(!flag)
語句來判斷程序的執行或終止。
3. 互斥訪問
3.1 修改TestUnSynchronizedThread.java源代碼使其可以同步訪問。(關鍵代碼截圖,需出現學號)
4. 互斥訪問與同步訪問
完成題集6-4(互斥訪問)與6-5(同步訪問)
4.1 除了使用synchronized修飾方法實現互斥同步訪問,還有什么辦法可以使用synchronized實現互斥同步訪問,使用代碼說明(請出現相關代碼及學號)?
public static void addId() {synchronized (Counter.class) {id++;}
}
用synchronized的同步代碼塊實現互斥同步訪問
4.2 同步代碼塊與同步方法有何區別?
同步代碼塊 :
即有synchronized關鍵字修飾的語句塊。
被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
方法如下:
synchronized(object){ }
同步方法?:
? ? 即有synchronized關鍵字修飾的方法。?
? ? 由于java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,?
? ? 內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處于阻塞狀態。
方法:
public synchronized void save(){}
4.3 實現互斥訪問的原理是什么?請使用對象鎖概念并結合相應的代碼塊進行說明。當程序執行synchronized同步代碼塊或者同步方法時,線程的狀態是怎么變化的?
原理:對象鎖,在程序中,每個對象都有一把鎖,只有獲得了對象鎖,才能執行相應的synchronized代碼塊或者方法,共享資源在一個時間段內只允許一個線程訪問,訪問完了另一個線程才能訪問,運用synchronized關鍵字代碼如下;
class Counter {private static int id = 0;public synchronized static void addId() {id++;}public synchronized static void subtractId() {id--;}public static int getId() {return id;}
}
某一線程競爭獲得對象鎖,其余線程在等待池中等待線程釋放對象鎖,當線程釋放對象鎖其余線程又開始競爭對象鎖,直到程序結束
4.4 Java多線程中使用什么關鍵字實現線程之間的通信,進而實現線程的協同工作?
使用wait ()、notify()、notifyAll()關鍵字實現線程之間的通信
5. 線程間的合作:生產者消費者問題
5.1 運行MyProducerConsumerTest.java。正常運行結果應該是倉庫還剩0個貨物。多運行幾次,觀察結果,并回答:結果正常嗎?哪里不正常?為什么?
兩次放入取出相同,但結果卻不一樣;因為producer和consumer的存取速度不一致,線程之間沒有合作就會產生錯亂
5.2 使用synchronized, wait, notify解決該問題(關鍵代碼截圖,需出現學號)
6. 面向對象設計作業-圖書館管理系統
6.1 系統的功能模塊表格,表格中體現出每個模塊的負責人。
6.2 運行視頻
6.3 講解自己負責的模塊,并粘貼自己負責模塊的關鍵代碼(出現學號及姓名)。
3.碼云及PTA
3.1. 碼云代碼提交記錄
3.2 截圖"多線程"PTA提交列表
3.3 統計本周完成的代碼量
周數 | 行數 | 新增行數 | 文件數 | 新增文件數 |
---|---|---|---|---|
第一周 | 39 | 39 | 9 | 9 |
第二周 | 278 | 239 | 18 | 9 |
第三周 | 431 | 153 | 33 | 15 |
第四周 | 894 | 182 | 51 | 9 |
第五周 | 1154 | 260 | 67 | 16 |
第六周 | 1354 | 200 | 79 | 12 |
第七周 | 1463 | 109 | 85 | 6 |
第八周 | 1776 | 313 | 101 | 16 |
第九周 | 1903 | 127 | 106 | 5 |
第十周 | 2136 | 233 | 122 | 16 |
第十一周 | 2861 | 725 | 146 | 24 |