一、繼承方式實作多線程和實作方式實作多線程對比
1、繼承方式(繼承thread類)
(1)實作步驟
a、将類聲明為 thread 的子類;
b、該子類應重寫 thread 類的 run 方法;
c、在主線程進行該自定義的線程類的對象的建立。
(2)實作特點
a、啟動線程時,不使用run()方法原因:ran()方法不能作為啟動線程的方法,該方法的調用相當于普通方法,并不能展現出線程執行的随機性。
b、啟動線程用start()方法,start()方法通過jvm調用run()方法。一個線程不能連續啟動,會出現非法狀态異常。
2、實作方式(實作runnabl接口,優于繼承方式)
a、自定義一個類,實作runnable接口;
b、實作接口中的run方法,對耗時的代碼進行操作;
c、然後在主線程中建立該了對象,将該類對象做為一個資源類,建立threadd類的對象,将剛才的資源類作為參數進行傳遞。
(2)實作特點(優于繼承方式的優勢)
a、避免了java單繼承的局限性。
b、更符合java面向對象的一種設計原則(面向接口程式設計),将代碼的實作和資源對象有效分離,即資料分離原則。
二、多線程的生命周期
多線程的生命周期:線程從開始建立到線程執行,最終到線程終止的過程。階段如下:
1、建立線程:此時線程無執行資格;
2、線程就緒:有執行資格,無執行權;
3、線程阻塞狀态(可能會出現):線程睡眠sleep()或線程等待wait();
4、喚醒狀态(可能會出現):notify(),喚醒之後執行階段5;
5、線程執行:start(),有執行資格,有執行權;
6、線程死亡:線程執行完畢,會被垃圾回收線程中的垃圾回收器及時從記憶體中釋放掉。
三、多線程安全
1、校驗一個多線程程式是否有安全問題的隐患的前提條件
(1)目前程式是否是多線程環境;
(2)是否有共享資料;
(3)是否有多條語句對共享資料進行操作。
2、解決方案
(1)方案:前兩個條件無法解決,通過解決條件(3)解決多線程安全問題,即:将多條語句對共享資料操作的代碼,用代碼塊包起來,即同步代碼塊。
(2)格式:
synchronized(鎖對象){
針對多條語句對共享資料操作代碼;
}
(3)鎖對象:任意的java類對象,一般是引用類型。每個線程最終使用的鎖,隻能是同一把鎖。
四、同步代碼塊(隐式鎖)
1、格式:
2、例如:
(1)資源類:
(2)測試類:
五、同步方法
1、同步方法:用synchronized聲明的方法。
2、鎖對象:
(1)靜态同步方法:類名.class
(2)非靜态同步方法:this
3、例如:
(1)資源類
(2)測試類
六、lock接口(顯示鎖)
1、概述:lock 實作提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。此實作允許更靈活的結構。 可以使用lock鎖進行具體的鎖定操作類,提供了具體的實作類:reentrantlock。加鎖并釋放鎖。
2、方法:
(1)加鎖:lock(),在對共享資料操作前擷取鎖。
(2)釋放鎖:unlock(),使用完畢之後釋放鎖。
3、顯示擷取鎖的前提:必須建立lock對象。
4、存在問題:使用lock鎖解決多線程安全問題,會存在問題:(1)執行效率低;(2)産生死鎖。
七、死鎖
1、死鎖:兩個或兩個以上的線程,在執行的過程中出現互相等待的情況,即為死鎖。
2、解決:生産者消費模式。需保證生産者線程和消費者線程針對同一個對象進行操作,
在外部建立一個學生對象,将這個學生對象通過構造方法傳入到各個線程中。
4、在消費者線程和生産者線程中加入循環(多線程)
(1)出現問題:a、同一個對象出現多次;b、資訊不比對。
(2)原因:a、cpu的一點點時間片,在某一個時間點可執行多次。b、線程具有随機性。
(3)解決:用synchronized(或lock鎖)同步代碼塊将多條語句對共享資料的操作包起來。
(4)解決之後依舊存在問題:資料無法依次列印。
(5)解決:等待喚醒機制
八、等待喚醒機制
1、核心思想
(1)生産者線程産生資料,若本身無資料,等待其産生資料,若有資料,通知(喚醒)對方(消費者程序)輸出資料。
(2)消費者線程消費資料,有資料,等待消費者線程先輸出資料,一旦無資料,及時通知(喚醒)對方(生産者線程)産生資料。
2、(面試題)wait(),notify(),notifyall() 這些方法為什麼會定義在object類中?
解:這些方法是主要用于線程的方法,而thread類中并沒有這些方法,多線程中同步鎖對象是任意的java類這些方法都和鎖對象有關系,是以定義在object類中。
九、線程組
1、概述:線程組,threadgroup,表示多個線程所在的集合。此外,線程組也可以包含其他線程組。
2、構造方法
(1)public threadgroup(string name)構造一個新線程組。
(2)thread(threadgroup group, runnable target, string name)構造線程組中的某個線程。
3、擷取方法
(1)public final threadgroup getthreadgroup()傳回該線程所屬的線程組。
(2)public final string getname()傳回線程組的名稱
十、線程池(多線程第三種實作方式)
1、特點
(1)節約成本。
(2)線程執行完畢後不會變成垃圾,重新回到線程池中,等待被利用。
2、executors類
(1)概述:一種工廠類,與線程池建立有關。
(2)方法:public static executorservice newfixedthreadpool(int nthreads)建立一個可重用固定線程數的線程池。
3、executorservice接口
(1)概述:可以執行異步任務,建立一個線程池,執行接口中的方法。
(2)送出:future<?> submit(runnable task)
<t> future<t> submit(callable<t> task)送出一個傳回值的任務用于執行,傳回一個表示任務的未決結果的 future。
4、future接口:future 表示異步計算的結果。
5、關閉線程池方法:void shutdown()線程池調用完畢可以關閉的,關閉之前,會送出剛才的任務。
6、實作多線程前提:自定義類實作callable接口。callable接口的泛型是call()方法的傳回值類型。
7、實作步驟
(1)自定義一個類實作callable<v>接口,并重寫call()方法,接口泛型與call()方法傳回值類型一樣。
(2)建立線程池對象:executors 裡面的方法,傳回的是executorsservice
(3)調用executorsservice裡面的送出任務的方法:
<t> future<t> submit(callable<t> task)送出一個傳回值的任務用于執行
(4)關閉線程池。
十一、面向對象設計原則/設計方法(23種)
1、重點
(1)設計模式:a、簡單工廠模式;b、工廠設計模式;c、單例設計模式(多線程),分為餓漢式和懶漢式。
(2)設計原則:a、關閉原則;b、接口分離原則。
2、面向對象設計原則
(1)單一職責原則:低耦合,高内聚。耦合性,類與類之間産生的關系。低耦合,讓類與類之間的關系不複雜。内聚:執行一個件事情(功能)的能力。高内聚,一個類能夠完成的事情,不要使用多個類一起來執行。
(2)開閉原則(重點):(核心思想)一個對象對擴充開放,對修改關閉。開發好一個程式(項目),盡量不要修改原有代碼。借助抽象和多态,把可能變化的内容抽象出來,抽象的部分是相對穩定的,而具體的改變則是可以改變和擴充的。
(3)裡氏替換原則:(核心思想)在任何父類出現的地方都可以用它的子類來替代。即:同一個繼承體系中的對象應該有共同的行為特征。
(4)依賴注入原則:spring mvc(開源架構)—mvc設計模式。(核心思想)要依賴于抽象,不要依賴于具體實作。即在應用程式中,所有的類如果使用或依賴于其他的類,則應該依賴這些其他類的抽象類,而不是這些其他類的具體類。為了實作這一原則,就要求在程式設計的時候針對抽象類或者接口程式設計,而不是針對具體實作程式設計。
(5)接口分離原則(重點):(核心思想)不應該強迫程式依賴它們不需要使用的方法。即一個接口不需要提供太多的行為,一個接口應該隻提供一種對外的功能,不應該把所有的操作都封裝到一個接口中。
(6)迪米特原則:(核心思想)一個對象應當對其他對象盡可能少的了解。即降低各個對象之間的耦合,提高系統的可維護性。在子產品之間應該隻通過接口程式設計,而不理會子產品的内部工作原理,它可以使各個子產品耦合度降到最低,促進軟體的複用。
3、面向對象設計模式
(1)簡單工廠模式(靜态工廠方法模式)
a、核心思想:定義一個具體的工廠類負責建立一些類的執行個體。
b、優點:用戶端不需要在負責對象的建立,進而明确了各個類的職責。
c、缺點:靜态工廠類負責所有對象的建立,如果有新的對象增加,或者某些對象的建立方式不同,就需要不斷的修改工廠類,不利于後期的維護。
(2)工廠方法模式
a、核心思想:工廠方法模式中抽象工廠類負責定義建立對象的接口,具體對象的建立工作由繼承抽象工廠的具體類實作。
b、優點:用戶端不需要在負責對象的建立,進而明确了各個類的職責,如果有新的對象增加,隻需要增加一個具體的類和具體的工廠類即可,不影響已有的代碼,後期維護容易,增強了系統的擴充性。
c、缺點:需要額外的編寫代碼,增加了工作量。
(3)單例設計模式(重點)
a、單例模式:要確定類在記憶體中隻有一個對象,該執行個體必須自動建立,并且對外提供。servlet程式(優化伺服器開發的) 單例。
b、優點:在系統記憶體中隻存在一個對象,是以可以節約系統資源,對于一些需要頻繁建立和銷毀的對象單例模式無疑可以提高系統的性能。
c、缺點:沒有抽象層,是以擴充很難。職責過重,在一定程式上違背了單一職責。
d、分類:
a、餓漢式(開發常用,不會出現問題);
b、懶漢式(類似于多線程環境,面試常用,可能會出現問題)。解決:同步機制或靜态同步方法。
e、餓漢式
a、特點:在加載那個類的時候,對象的建立工作已經完成。
b、設計步驟:
(a)定義個類,将該類的無參構造方法私有化;
(b)在該類的成員位置建立該類對象,并且一定要私有化,防止外界更改這個對象;
(c)在該類中提供靜态成員方法(傳回值就是建立的對象),能被目前類直接調用,static修飾。
f、懶漢式(延遲加載→懶加載)
a、設計步驟:單例模式核心思想
(a)自定義一個類,将無參構造私有化;
(b)在成員位置聲明變量;
(c)提供公共靜态功能,在裡面判斷的建立該類對象,傳回該類對象。
b、可能出現的問題:同多線程環境問題。
c、解決:使用同步機制解決。
(4)(面試題)你使用過單例模式嗎?簡單介紹一種單例模式,請用代碼設計。
核心思想:使用設計單例的懶漢式,想到使用同步機制解決線程的安全問題。
十二、runtime類
1、概述:每個 java 應用程式都有一個 runtime 類執行個體,使應用程式能夠與其運作的環境相連接配接。
(1)public static runtime getruntime()傳回與目前 java 應用程式相關的運作時對象。
(2)public process exec(string command) throws ioexception在單獨的程序中執行指定的字元串指令。
十三、網絡程式設計
1、計算機網絡:多台計算機通過網絡協定,實作網絡資源共享和資訊傳遞。
2、網絡通信三要素:ip位址、端口号、傳輸協定/規則(udp/tcp)。
3、ip位址:
(1)組成:網絡号碼+主機位址
(2)分類:
a、a類ip位址:第一段号碼為網絡号碼,剩下的三段号碼為本地計算機的号碼
一般用于:國防部/大的國家部門。
b、b類ip位址:前二段号碼為網絡号碼,剩下的二段号碼為本地計算機的号碼
一般用于:大學裡面的多媒體教室。
c、c類ip位址:前三段号碼為網絡号碼,剩下的一段号碼為本地計算機的号碼
一般用于:私人位址。(網際網路不使用,被用在區域網路中的位址)。
4、端口号:
(1)有效端口号:0~65535
(2)保留端口号:0~1024(暫時不用)
(3)360軟體可查詢端口号。
5、傳輸協定:
(1)udp協定(udp程式設計):不需要建立連接配接通道,資料大小有限制,不可靠連接配接,執行效率高。例如:發資訊,無需建立連接配接通道,可看做udp協定。
(2)tcp協定(tcp程式設計):需要建立連接配接通道,資料大小無限制,可靠連接配接,執行效率低。例如:打電話,建立連接配接通道,可看做tcp協定。
十四、inetaddress類
1、概述:表示網際網路協定 (ip) 位址。無構造方法,無字段,無成員方法。
2、一個類中沒有構造方法,沒有字段,隻有成員方法的特征:
(1)應該有一些靜态功能;
(2)可能符合一種單例模式(餓漢/懶漢);
(3)該類中的某些靜态成員方法的傳回值是該類本身。
3、常用方法:
(1)public static inetaddress getbyname(string host)在給定主機名的情況下确定主機的 ip 位址。
異常:throws unknownhostexception
參數:主機名可以是機器名(如 "java.sun.com"),也可以是其 ip 位址的文本表示形式。
(2)public string gethostaddress()傳回 ip 位址字元串(以文本表現形式)。
(3)public string gethostname()擷取此 ip 位址的主機名。
十五、udp程式設計開發步驟
1、udp程式設計發送端開發步驟:
(1)建立發送端的socket對象;
(2)建立資料,并打包;
(3)調用目前發送端socket對象中的發送的方法;
(4)關閉資源。
2、udp程式設計發送端開發常用方法:
(1)public datagramsocket(int port,inetaddress laddr)構造方法,建立發送端的socket對象。(datagramsocket-此類表示用來發送和接收資料報包的套接字。)
(2)datagrampacket(byte[] buf, int offset, int length, inetaddress address, int port) 建立資料,并打包。( buf-包資料,offset - 包資料偏移量,length - 包資料長度,address - 目的位址,port - 目的端口号
)
(3)public void send(datagrampacket p)throws ioexception從此套接字發送資料報包。
3、udp程式設計接收端開發步驟:
(1)建立socket對象;
(2)建立一個資料報包(接收容器);
(3)調用socket對象中的接收方法;
(4)解析實際傳遞的資料;
(5)将解析的資料(ip,資料)展示在控制台上;
(6)關閉資源。
4、udp程式設計接收端開發常用方法:
(1)public datagramsocket(int port)建立資料報包套接字對象并且将其綁定到本地主機上的指定端口。
(2)public datagrampacket(byte[] buf, int length)建立一個資料報包(接收容器)。
(3)public void receive(datagrampacket p)接收資料報包。
(4)public inetaddress getaddress()擷取ip位址文本形式,傳回ip位址對象,資料報包類:datagrampacket。
(5)public byte[] getdata()擷取緩沖中實際資料(從接收容器中擷取)。
(6)public int getlength()傳回将要發送或接收到的資料的長度。
5、注意:接收端不要運作多次,會出現異常。java.net.bindexception: address already in use: cannot bind。