學號:201621123032 《Java程序設計》第11周學習總結
1:本周學習總結
1.1.:以你喜歡的方式(思維導圖或其他)歸納總結多線程相關內容。
2:書面作業
2.1.: 源代碼閱讀:多線程程序BounceThread
1.1: BallRunnable類有什麽用?為什麽代碼中需要調用Thread.sleep進行休眠?
BallRunnable類中的run方法循環調用move函數和repaint函數,來畫出小球的移動軌跡。使用了Thread.sleep來使線程休眠。
休眠是為了讓我們可以看到小球的移動,不然程序會很快完成,我們沒辦法觀察到小球的移動軌跡。
1.2:Ball.java只做了兩件事,這兩件事分別是什麽?BallComponent對象是幹什麽的?其內部的ArrayList有什麽用?程序運行過程中,生成了幾個BallComponent對象?該程序使用了多線程技術,每個小球是分別在不同的線程中進行繪制嗎?
兩件事:
- move函數是小球的移動的方式。
getShape函數是返回小球的坐標。
BallComponent對象是用來添加一個小球,內部的ArrayList用來存放新添加的小球。?程序運行過程中生成了1個BallComponent對象。每個小球是在自己的線程裏進行繪制的。2.2.:實驗總結:題集(多線程)
2.1:題目:Thread、PrintTask、Runnable與匿名內部類。
並回答:a)通過定義Runnable接口的實現類來實現多線程程序比通過繼承自Thread類實現多線程程序有何好處?b) 6-1,6-3,6-11實驗總結。
a:一個類只能繼承一個父類,存在局限。而一個類可以實現多個接口,在實現Runnable接口的時候調用Thread的Thread(Runnable run)構造方法創建進程時,使用同一個Runnable實例,建立的多線程的實例變量也是共享的;但是通過繼承Thread類是不能用一個實例建立多個線程。
b:
- 6-1:本題編寫MyThread類繼承自Thread,在run方法中實現打印功能
6-3:多線程使用匿名內部類可以繼承thread類實現多線程,也可以實現runnable接口,創建多線程並啟動。本題還要註意 主線程名是mainThreadName,線程t1的線程名是Thread.currentThread().getName()
6-11 不同於第一題的繼承Tread類,本題我采用了實現Runnable接口的方法。runf方法與第一題一樣。
2.2.:使用Lambda表達式改寫6-3
2.3:題目:6-2(Runnable與停止線程)。回答:需要怎樣才能正確地停止一個運行中的線程?
在java中有以下3種方法可以終止正在運行的線程:
使用退出標誌,使線程正常退出,也就是當run方法完成後線程終止。
使用stop方法強行終止,但是不推薦這個方法,因為stop和suspend及resume一樣都是過期作廢的方法。
使用interrupt方法中斷線程。
2.3:互斥訪問
3.1:修改TestUnSynchronizedThread.java源代碼使其可以同步訪問。(關鍵代碼截圖,需出現學號)
//201621123032
//王彩雲
class Counter {
private static int id = 0;
public static synchronized void addId() {
id++;
}
public static synchronized void subtractId() {
id--;
}
public static int getId() {
return id;
}
運行結果:
2.4:互斥訪問與同步訪問
4.1:除了使用synchronized修飾方法實現互斥同步訪問,還有什麽辦法可以使用synchronized實現互斥同步訪問,使用代碼說明(請出現相關代碼及學號)?
4.2:同步代碼塊與同步方法有何區別?
同步代碼塊是在方法內部加鎖,,同步方法直接在方法上加synchronized實現加鎖,同步方法鎖的範圍比較大,而同步代碼塊範圍要小點,一般同步的範圍越大,性能就越差。
4.3:實現互斥訪問的原理是什麽?請使用對象鎖概念並結合相應的代碼塊進行說明。當程序執行synchronized同步代碼塊或者同步方法時,線程的狀態是怎麽變化的?
java中的每個對象都有一個鎖,當訪問某個對象的synchronized方法時,表示將該對象上鎖,此時其他任何線程都無法在去訪問該syncronized 方法了,直到之前的那個線程執行方法完畢後,其他線程才有可能去訪問該synchronized方法。
class test implements Runnable{
public int a;
public void run() {
synchronized(this) {
a++;
try {
System.out.println("當前線程---"+Thread.currentThread().getName()+"---a--"+a);
Thread.sleep(5000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class boketest {
public static void main(String[] args) {
test sc=new test();
test sc1=new test();
Thread th1=new Thread(sc);
Thread th2=new Thread(sc);
th1.start();
th2.start();
}
運行結果:
第二行結果是間隔5秒才打印的,由於synchronzied實現了互斥,且只有sc這個對象鎖,所以當第一個線程鎖住了sc,而第二個線程裏面也是通過sc去訪問run()方法,所以必須等第一個線程執行完對象的方法時才能獲得對象鎖。因此必須隔5秒鐘才能執行第二個線程
4.4:Java多線程中使用什麽關鍵字實現線程之間的通信,進而實現線程的協同工作?
使用wait ()、notify()、notifyAll()關鍵字實現線程之間的通信,進而實現線程的協同工作。
2.5:線程間的合作:生產者消費者問題
5.1:運行MyProducerConsumerTest.java。正常運行結果應該是倉庫還剩0個貨物。多運行幾次,觀察結果,並回答:結果正常嗎?哪裏不正常?為什麽?
不正常。運行結果有時候倉庫剩下的貨物為非0個。這是因為線程之間沒有合作,出現供需不一致的情況。
5.2:使用synchronized, wait, notify解決該問題(關鍵代碼截圖,需出現學號)
代碼修改:
//201621123032
//王彩雲
public synchronized void add(String t) {
if (repo.size() == capacity) {
try {
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
if (repo.size() >= capacity) {
System.out.println("倉庫已滿!無法添加貨物。");
} else {
repo.add(t);
}
notify();
}
public synchronized void remove() {
if (repo.size() == 0)
try {
wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
if (repo.size() <= 0) {
System.out.println("倉庫無貨!無法從倉庫取貨");
} else {
repo.remove(0);
}
notify();
}
運行結果:
2.6: 面向對象設計作業-圖書館管理系統(本題還未完等周日補上)
6.1:系統的功能模塊表格,表格中體現出每個模塊的負責人。
6.2: 運行視頻
6.3:講解自己負責的模塊,並粘貼自己負責模塊的關鍵代碼(出現學號及姓名)。
3:碼雲及PTA
3.1:碼雲代碼提交記錄
3.2:截圖"多線程"PTA提交列表
3.3:統計本周完成的代碼量
周次 | 總代碼量 | 新增加代碼量 | 總文件夾 | 新增加文件夾 |
---|---|---|---|---|
1 | 114 | 114 | 11 | 11 |
2 | 520 | 406 | 16 | 6 |
3 | 1089 | 569 | 22 | 6 |
5 | 1425 | 336 | 29 | 7 |
6 | 1819 | 394 | 31 | 2 |
7 | 2987 | 1168 | 54 | 23 |
8 | 5437 | 2450 | 79 | 25 |
9 | 5695 | 258 | 84 | 5 |
10 | 6680 | 985 | 102 | 18 |
11 | 6935 | 255 | 111 | 9 |
12 | 7401 | 466 | 123 | 12 |
學號:201621123032 《Java程序設計》第11周學習總結