1. 本周學習總結
1.1 以你喜歡的方式(思維導圖或其他)歸納總結多線程相關內容。
2. 書面作業
本次PTA作業題集多線程
1. 源代碼閱讀:多線程程序BounceThread
1.1 BallRunnable類有什么用?為什么代碼中需要調用Thread.sleep進行休眠?
答:BallRunnable
類實現了Runnable接口,旨在支持多線程,在類中對線程進行操控。代碼中調用Thread.sleep
是為了延緩線程的執行速度,否則線程執行的速度肉眼將無法看見,小球會直接出現在終點。
1.2 Ball.java只做了兩件事,這兩件事分別是什么?BallComponent對象是干什么的?其內部的ArrayList有什么用?程序運行過程中,生成了幾個BallComponent對象?該程序使用了多線程技術,每個小球是分別在不同的線程中進行繪制嗎?
答:Ball.java
中move()
方法控制小球的移動,getShape()
方法獲得小球的當前位置和大小。
BallComponen
t對象用來添加小球並畫出小球。其內部的ArrayList用來儲存當前的小球。
程序運行過程中只生成了一個BallComponent
對象。
每個小球是分別在不同的線程中進行繪制。每次點擊START
按鈕,都調用addBall()
方法產生一個新的線程。
1.3 選做:程序改寫:程序運行時,每個小球都是從固定位置出發。如何改寫該程序,使得當點擊start時,每個小球可以從不同位置出發、以不同的步進移動?
2. 實驗總結:題集(多線程)
2.1 題目:Thread、PrintTask、Runnable與匿名內部類。並回答:a)通過定義Runnable接口的實現類來實現多線程程序比通過繼承自Thread類實現多線程程序有何好處?b) 6-1,6-3,6-11實驗總結。
答:
(a)一個類只能繼承一個父類,但是可以聲明若干接口,使用接口來實現多線程可以避免繼承的局限性,使此類仍可以繼承其他類。
繼承Thread類實現任務時,在new繼承類的時候在創建三個對象的同時創建了三個線程,各自完成各自的任務。而使用Runnable接口則創建三個線程即安排三個窗口去執行任務,實現了資源共享。
(b)
6-1 jmu-Java-07多線程-Thread
這題比較簡單,用在run()中循環輸出即可。
6-11 jmu-Java-07多線程-PrintTask
和6-1類似,標識信息不同
6-3 jmu-Java-07多線程-Runnable與匿名類
使用Lamda表達式實現一個匿名類打印信息
2.2 使用Lambda表達式改寫6-3
Thread thread= new Thread(() -> {
System.out.println(mainThreadName);
System.out.println(Thread.currentThread().getName());
System.out.println(Arrays.toString(Thread.class.getInterfaces()));
});
2.3 題目:6-2(Runnable與停止線程)。回答:需要怎樣才能正確地停止一個運行中的線程?
此題主要是編寫stopMe()方法,用一個boolean變量來控制線程的停止。
答:定義boolean型變量作為循環條件,要停止線程時改變變量值即可。
Thread
類提供stop
方法用於停止線程,但此方法會強行終止線程無論線程是否運行完畢、釋放,已經是不推薦使用的方法。
2.4 選做:6-8(CountDownLatch)實驗總結
關鍵語句:ExecutorService exec = Executors.newFixedThreadPool(poolSize);
使n個任務用m個線程完成
2.5 選做:6-9(集合同步問題)實驗總結
使用synchronizedList
關鍵字修飾ArrayList即可解決同步問題
3. 互斥訪問
3.1 修改TestUnSynchronizedThread.java源代碼使其可以同步訪問。(關鍵代碼截圖,需出現學號)
3.2 選做:進一步使用執行器改進相應代碼(關鍵代碼截圖,需出現學號)
參考資料:Java多線程之Executor、ExecutorService、Executors、Callable、Future與FutureTask
4. 互斥訪問與同步訪問
完成題集6-4(互斥訪問)與6-5(同步訪問)
4.1 除了使用synchronized修飾方法實現互斥同步訪問,還有什么辦法可以使用synchronized實現互斥同步訪問,使用代碼說明(請出現相關代碼及學號)?
還可以使用synchronized代碼塊
4.2 同步代碼塊與同步方法有何區別?
答:同步代碼塊是將synchronized
加在方法體中,使部分代碼加鎖,而同步方法是用synchronized
修飾方法名,使整個方法加鎖。前者性能優於后者,但作用范圍后者更大
4.3 實現互斥訪問的原理是什么?請使用對象鎖概念並結合相應的代碼塊進行說明。當程序執行synchronized同步代碼塊或者同步方法時,線程的狀態是怎么變化的?
答:通俗的說就是給線程共享的資源上鎖,某時間段內只允許按照特定的線程對其進行訪問。
public class TreadTest implements Runnable {
private int count = 5;
public static void main(String[] args) {
TreadTest tread = new TreadTest();
Thread t1 = new Thread(tread);
Thread t2 = new Thread(tread);
t1.start();
t2.start();
}
public synchronized void run()
{
while(count > 0)
{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
System.out.println("CountsLeft:" + count);
count --;
}
}
}
4.4 Java多線程中使用什么關鍵字實現線程之間的通信,進而實現線程的協同工作?
synchronized
關鍵字和wait/notify
方法
5. 線程間的合作:生產者消費者問題
5.1 運行MyProducerConsumerTest.java。正常運行結果應該是倉庫還剩0個貨物。多運行幾次,觀察結果,並回答:結果正常嗎?哪里不正常?為什么?
結果不正常。貨物的存取應該采用互斥同步訪問,Producer和customer的存取速度沒有協調好導致可能庫空時就開始取貨,或庫滿還沒出貨時又有商品進庫。
5.2 使用synchronized, wait, notify解決該問題(關鍵代碼截圖,需出現學號)
運行截圖:
關鍵代碼:
5.3 選做:使用Lock與Condition對象解決該問題。
運行截圖:
關鍵代碼:
6. 面向對象設計作業-圖書館管理系統
6.1 系統的功能模塊表格,表格中體現出每個模塊的負責人。
6.2 運行視頻
6.3 講解自己負責的模塊,並粘貼自己負責模塊的關鍵代碼(出現學號及姓名)。
關鍵點:圖書館管理系統使用.obj文件來保存圖書信息和讀者信息,可以做到隨時運行程序都能從文件從讀取圖書信息和讀者信息
文件存取:使用FileInputStream和FileOutputStream存取文件
登錄:讀取Readers_info.obj
中存放所有讀者信息的Map,根據學號key值取對應的Reader對象,再比較密碼是否正確
書庫:讀取Books_info.obj
中存放書籍信息的map,遍歷map的value用JTable展示出來
借書:登錄后把reader作為參數傳入構造函數,借書成功后對存放書籍的文件和存放讀者信息的文件進行更新重寫
還書:讀取Readers_info.obj
中對應此reader的value對象,把已借的書用JTable顯示出來,還書成功后同樣對存放書籍的文件和存放讀者信息的文件進行更新重寫
搜索:將搜索出的書籍以List的形式返回,在搜索結果界面中用JTable顯示出來
PS:目前只簡易實現了讀者借閱、還書、搜索模塊,因為研究文件讀寫造成時間有點緊張,管理員的部分(添加、刪除、調整書籍)在類中寫了方法,沒來得及圖形化
還有讀者部分的修改密碼、圖書可以直接點擊JTable產生借還書事件等想法,沒來得及實現
3.碼雲及PTA
題目集:多線程
3.1. 碼雲代碼提交記錄
在碼雲的項目中,依次選擇“統計-Commits歷史-設置時間段”, 然后搜索並截圖
必須出現幾個要素:提交日期-用戶名(姓名與學號)-不提交說明
3.2 截圖"多線程"PTA提交列表
需要有兩張圖(1. 排名圖。2.PTA提交列表圖)
3.3 統計本周完成的代碼量
需要將每周的代碼統計情況融合到一張表中。
周次 | 行數 | 新增行數 | 文件數 | 新增文件數 |
---|---|---|---|---|
1 | 226 | 226 | 45 | 45 |
2 | 377 | 377 | 7 | 7 |
3 | 712 | 281 | 42 | 9 |
4 | 166 | 166 | 2 | 2 |
5 | 253 | 253 | 4 | 4 |
6 | 484 | 484 | 9 | 9 |
7 | 269 | 269 | 1 | 1 |
8 | 301 | 32 | 5 | 4 |
9 | 447 | 447 | 7 | 7 |
10 | 401 | 26 | 9 | 0 |
11 | 1262 | 1262 | 18 | 18 |
5. 選做:學會使用Eclipse進行調試
5.1 簡述使用Eclipse進行調試需要幾步?調試時F5, F6, F7快鍵鍵各有什么不同?什么情況該使用哪個快捷鍵?
1.雙擊代碼左側行號打斷點
2.進入debug進行查看調試
F5:單步調試,遇到方法時進入方法中進行調試
F6:單步調試,跳過方法。在無需調試某方法時使用
F7:單步調試,跳出當前方法。想跳出某方法時使用