學(xué)習(xí)筆記20170601">【PMP】學(xué)習(xí)筆記20170601
649
2022-05-29
異常
異常的超類java.lang.Throwable
Throwable:包括Error和Exception
Exception:編譯期異常,包括:RuntimeException:運(yùn)行期異常
JVM檢測(cè)程序出現(xiàn)異常:
JVM會(huì)根據(jù)異常產(chǎn)生的原因創(chuàng)建一個(gè)異常對(duì)象,這個(gè)異常對(duì)象包括異常產(chǎn)生的(內(nèi)容,原因,位置);
在getElement方法中,沒(méi)有異常處理邏輯{ try…catch},那么JVM會(huì)把異常對(duì)象拋給方法的調(diào)用者main方法來(lái)處理這個(gè)異常;
main方法里也沒(méi)有異常邏輯,繼續(xù)把對(duì)象拋出給main方法的調(diào)用者JVM;
JVM接收到異常對(duì)象,先進(jìn)行打印異常對(duì)象,再終止正在執(zhí)行的java程序–>中斷處理
使用throw關(guān)鍵字在指定的方法中拋出指定的異常
使用格式:throw new xxxException(“異常產(chǎn)生原因”);
注意:
1.throw關(guān)鍵字必須寫(xiě)在方法內(nèi)部
2.throw關(guān)鍵字后面的new的對(duì)象必須是Exception或者Exception子類對(duì)象
3.throw關(guān)鍵字拋出指定的異常,必須處理這個(gè)異常對(duì)象(編譯期異常必須處理:throws/try…catch),但是throw關(guān)鍵字后面創(chuàng)建的RuntimeException或者RuntimeException的子類對(duì)象,可以不處理,交給JVM進(jìn)行處理
獲取數(shù)組指定索引處問(wèn)題:必須校驗(yàn)傳遞的參數(shù)(數(shù)組)的合法性:
數(shù)組為空:空指針異常(NullPointerException) 運(yùn)行期異常
數(shù)組索引不存在:數(shù)組索引越界異常(ArrayIndexOutOfBoundsException) 運(yùn)行期異常
集合越界:IndexOutOfBoundsException
ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
Objects由一些靜態(tài)方法組成,容忍null-save(空指針安全)或null-tolerant(容忍空指針)
public static T requireNonNull(T obj) :查看指定引用對(duì)象不是null
空指針異常:throw new NullPointerException(“xxx”)
調(diào)用方法:Objects.requireNonNull(obj);
重載:Objects.requireNonNull(obj, “xxx”); //拋出xxx
異常處理的第一種方式,交給別人處理,異常后面的代碼不執(zhí)行
作用:
當(dāng)方法內(nèi)部拋出異常對(duì)象時(shí),我們必須處理這個(gè)異常對(duì)象
使用throws關(guān)鍵字處理異常對(duì)象,會(huì)將異常對(duì)象聲明拋出給方法的調(diào)用者,最終交給JVM處理–>中斷處理
修飾符 返回值類型 方法名( 參數(shù)列表 ) throws AAAException, BBBException{
throw new AAAException(“XXX”); throw new BBBException(“XXX”); }
注意:
throws關(guān)鍵字必須再在方法聲明處
throws關(guān)鍵字后面聲明的異常必須是Exception或者Exception的子類
方法內(nèi)部有幾個(gè)異常對(duì)象,那么throws后面必須也聲明幾個(gè)異常,如果拋出的多個(gè)異常有子父類關(guān)系,直接聲明父類異常就可以
調(diào)用了一個(gè)聲明保存異常的方法,就必須處理聲明的異常:繼續(xù)throws拋出 /try…catch,讓方法的調(diào)用者處理,使用try…catch,throw 的XXX不打印。直接打印catch里面的內(nèi)容
FileNotFoundExcption(文件路徑不對(duì))是編譯異常,拋出編譯異常,就必須處理這個(gè)異常:throws
IOException(文件后綴名不對(duì))
FileNotFoundExcption extends IOException 只聲明IOException就行
throw拋出編譯異常,throws進(jìn)行處理異常
try{ 可能產(chǎn)生異常的代碼 }catch(定義一個(gè)異常遍歷,用來(lái)接受try拋出的異常對(duì)象){ 異常處理邏輯 + 記錄到日志中 }
1
2
3
4
注意:
try多個(gè)異常,則使用多個(gè)catch
處理完catch,繼續(xù)執(zhí)行try…catch后面的代碼,同時(shí)try在異常后面的代碼不執(zhí)行
Throwable類的方法
getMessage() : 返回此throwable的描述
toString():返回此throwable的詳細(xì)消息字符串
printStacKTrace() JVM打印異常對(duì)象,默認(rèn)
try{ 可能產(chǎn)生異常的代碼 }catch(IOException e){ sout(e.getMessage()) }
1
2
3
4
5
必須與try一起使用,一般用于資源釋放(回收),無(wú)論程序是否出現(xiàn)異常,都要進(jìn)行資源釋放(IO)
多個(gè)異常進(jìn)行處理
多個(gè)異常分別處理 多次try…catch
異常多個(gè)處理 try…catch…catch…catch
catch定義的異常變量,如果有子父類,子類異常變量必須寫(xiě)在父類上面。因?yàn)閠ry如果出現(xiàn)異常對(duì)象,會(huì)把異常對(duì)象拋給catch處理,異常對(duì)象會(huì)從上到下異常賦值給catch中的異常變量。可能會(huì)使用多態(tài)進(jìn)行子類轉(zhuǎn)換為父類。
多個(gè)異常一次捕獲一次處理 使用(Exception e )進(jìn)行處理—超類
運(yùn)行時(shí)異常可以不進(jìn)行處理不捕獲
finally有return,則會(huì)永遠(yuǎn)防護(hù)finally的結(jié)果,要避免這種情況。
父類拋出多個(gè)異常,子類重寫(xiě)父類方法時(shí)應(yīng)該也拋出和符類相同的異常或者父類異常的子類或者不拋出。
父類沒(méi)有拋出異常,子類重寫(xiě)父類方法時(shí)也不能拋出異常,只能捕獲
格式:
public class xxxException extends Exception | RuntimeException {
添加一個(gè)空參數(shù)的構(gòu)造方法;添加一個(gè)帶異常信息的構(gòu)造方法(方法內(nèi)部調(diào)用父類帶異常信息的構(gòu)造方法,讓父類進(jìn)行處理異常信息); }
繼承RuntimeException 運(yùn)行期異常,無(wú)需處理,交給JVM中斷處理
繼承Exception 編譯期異常,就要throws / try…catch
多線程
并發(fā):多個(gè)事件在同一個(gè)時(shí)間段內(nèi)發(fā)生。交替執(zhí)行。
并行:多個(gè)事件在同一個(gè)時(shí)時(shí)刻內(nèi)發(fā)生。同時(shí)執(zhí)行。
進(jìn)程:一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序,每一個(gè)進(jìn)程都要獨(dú)立的內(nèi)存空間,一個(gè)應(yīng)用程序可以同時(shí)運(yùn)行多個(gè)進(jìn)程,進(jìn)程是系統(tǒng)運(yùn)行程序的基本單位。
線程:是進(jìn)程的一個(gè)執(zhí)行單元,負(fù)責(zé)當(dāng)前進(jìn)程中程序的執(zhí)行,一個(gè)進(jìn)程中至少有一個(gè)線程,可以有多個(gè)線程–多線程程序。多個(gè)線程互不影響
分時(shí)調(diào)度:多個(gè)線程輪流使用CPU的使用權(quán),評(píng)價(jià)分配占用CPU的時(shí)間
搶占式調(diào)度:優(yōu)先讓優(yōu)先級(jí)高的線程使用CPU,優(yōu)先級(jí)相同,隨機(jī)選擇一個(gè)線程,java的使用為搶占式調(diào)度。
java是單線程,main函數(shù)從上到下執(zhí)行
java.lang.Thread類,描述線程的類,多線程程序要繼承 extends Thread類
第一種創(chuàng)建線程方式步驟
創(chuàng)建Thread類的子類
重寫(xiě)Thread類的run方法,設(shè)置線程任務(wù)
創(chuàng)建Thread類的子類對(duì)象
調(diào)用Thread類的方法start方法,開(kāi)始新的線程,java虛擬機(jī)調(diào)用該線程的run方法。結(jié)果是兩個(gè)線程:main線程和新線程(子類對(duì)象名.start(),執(zhí)行run)
內(nèi)存:會(huì)開(kāi)辟新的棧空間進(jìn)行執(zhí)行run方法
獲取線程名稱:String getName( ) 主線程:main 線程一:Thread-0
獲取線程:static Thread currentThread( ) 返回當(dāng)前正在執(zhí)行的線程對(duì)象的引用
Thread t = Thread.currentThread( ); – Thread[Thread-0, 5, main]
鏈?zhǔn)骄幊蹋篢hread.currentThread( ). getName( )
設(shè)置線程名稱:setName( String name) / Thread( String name)帶參數(shù)的構(gòu)造方法。傳遞參數(shù)名稱–線程名稱,父類給子線程類進(jìn)行起名,super(name)
sleep
public static void sleep ( long millis ) : 以毫秒數(shù)暫停
第二種創(chuàng)建線程方式
實(shí)現(xiàn)Runnable接口 implements Runnable ,java.lang.Runnable
Runnable接口應(yīng)該由那些打算通過(guò)某一線程執(zhí)行其實(shí)例的類來(lái)實(shí)現(xiàn)。類需要定義一個(gè)run的無(wú)參數(shù)方法。
Thread(Runnable target),分配新的Thread對(duì)象
Thread(Runnable target, String name)
步驟
實(shí)現(xiàn)Runnable接口的實(shí)現(xiàn)類 implements Runnable
實(shí)現(xiàn)類進(jìn)行重寫(xiě)Runnable接口的run方法,設(shè)置線程任務(wù)
創(chuàng)建Runnable接口的實(shí)現(xiàn)類對(duì)象
Runnable run = new RunnableImpl( ) ; //多態(tài)也可以
創(chuàng)建Thread類對(duì)象,在構(gòu)造方法中傳遞Runnable接口的實(shí)現(xiàn)類對(duì)象
Thread t = new Thread( run ); //因?yàn)槭莑ang類,不用導(dǎo)包
調(diào)用Thread類中的start迭代,開(kāi)啟新的線程執(zhí)行run方法 t.start( );
實(shí)現(xiàn)Runnable接口,避免了單繼承的局限性,因?yàn)橐粋€(gè)類只能繼承一個(gè)類。
實(shí)現(xiàn)Runnable接口,增強(qiáng)程序擴(kuò)展性,降低程序耦合性(解耦)。將設(shè)置線程任務(wù)和開(kāi)啟新線程進(jìn)行了分離。在實(shí)現(xiàn)類中重寫(xiě)run方法進(jìn)行設(shè)置線程任務(wù),創(chuàng)建Thread類對(duì)象,調(diào)用start方法,開(kāi)啟新線程。
如果一個(gè)類繼承Thread,則不適合資源共享。但是如果實(shí)現(xiàn)了Runable接口的話,則很容易的實(shí)現(xiàn)資源共享
匿名內(nèi)部類:將子類繼承父類,重寫(xiě)父類方法,合為一步。把實(shí)現(xiàn)類實(shí)現(xiàn)類接口,重寫(xiě)接口的方法,創(chuàng)建實(shí)現(xiàn)類對(duì)象合為一步。
new 父類/接口 ( ) { 重寫(xiě)父類/接口中的方法 }
繼承:new Thread( ) { @Override pubilc void run() { } }.start( );
接口1:Runable r = new Runable( ) { @Override pubilc void run() { } };
new Thread( r ).start( );
接口2:new Thread( new Runable( ) { @Override pubilc void run() { } } ).start( );
線程+同步
共享數(shù)據(jù)時(shí)會(huì)出現(xiàn)線程沖突,執(zhí)行語(yǔ)句時(shí)會(huì)失去CPU的使用權(quán),包括if,計(jì)數(shù)等操作語(yǔ)句。
同步操作
解決線程安全問(wèn)題
只讓一個(gè)線程在同步代碼塊中執(zhí)行,效率變低
synchronized(鎖對(duì)象) { 可能會(huì)出現(xiàn)的線程安全問(wèn)題的代碼(訪問(wèn)了共享數(shù)據(jù)的代碼) }
注意:
通過(guò)代碼塊中的鎖對(duì)象,可以使用任意的對(duì)象;
Object obj = new Object(); new Thread(){ @Override public void run() { try...catch synchronized( obj ) { try...catch / "XXX" } } } .start();
1
2
3
4
5
6
7
必須保證多個(gè)線程使用的鎖對(duì)象是同一個(gè)。
把訪問(wèn)共享數(shù)據(jù)的代碼抽取出來(lái),放到一個(gè)方法中,在方法上添加synchronized修飾符
修飾符 synchronized 返回值類型 方法名( 參數(shù)列表 ) { }
同步方法的鎖對(duì)象是實(shí)現(xiàn)類對(duì)象,就是this
靜態(tài)同步方法
靜態(tài)同步方法的鎖對(duì)象是本類的class屬性—>class文件對(duì)象( 反射 ),因?yàn)殪o態(tài)方法優(yōu)于對(duì)象,創(chuàng)建對(duì)象之后才有this。
java.util.concurrent.Locks.Lock接口
Lock接口方法:void lock( ) 獲取鎖;void unlock( ) 釋放鎖
Lock接口實(shí)現(xiàn)類:ReentrantLock
java.util.concurrent.Locks.ReentrantLock implements Lock
步驟:在成員位置創(chuàng)建一個(gè)ReentrantLock對(duì)象
Lock l = new ReentrantLock( );
l.lock( ) ; 獲取鎖 finally{ l.unlock( ) ; }
java.lang.Thread.State
新建狀態(tài) new Thread( )
阻塞狀態(tài):BLOCKED,CPU空閑執(zhí)行
運(yùn)行狀態(tài):RUNNABLE
休眠狀態(tài):TIMED_WAITING,計(jì)時(shí)等待,CPU空閑也不執(zhí)行
死亡狀態(tài):TERMINATED
無(wú)限等待:WAITING
調(diào)用Object.wait( ) 方法,無(wú)限等待 <
通信
> 調(diào)用Object.notify( ) [ Object.notifyAll( ) ]方法,結(jié)束等待,喚醒
wait( long m ) : wait方法在毫秒值結(jié)束之后還沒(méi)有醒過(guò)來(lái),則自動(dòng)醒來(lái)。
作業(yè)
throw關(guān)鍵字通常用在方法體中,并且拋出一個(gè)異常對(duì)象。程序在執(zhí)行到throw語(yǔ)句時(shí)立即停止,它后面的語(yǔ)句都不執(zhí)行。
throws關(guān)鍵字通常被應(yīng)用在聲明方法時(shí),用來(lái)指定可能拋出的異常。多個(gè)異常可以使用逗號(hào)隔開(kāi)。當(dāng)在主函數(shù)中調(diào)用該方法時(shí),如果發(fā)生異常,就會(huì)將異常對(duì)象拋給方法調(diào)用處。
異常
**NullPointerException:**空指針異常。
當(dāng)應(yīng)用試圖在要求使用對(duì)象的地方使用了null時(shí),拋出該異常。譬如:調(diào)用null對(duì)象的實(shí)例方法、訪問(wèn)null對(duì)象的屬性、計(jì)算null對(duì)象的長(zhǎng)度等等。
**ArrayIndexOutOfBoundsException:**數(shù)組索引越界異常。
當(dāng)對(duì)數(shù)組的索引值為負(fù)數(shù)或大于等于數(shù)組大小時(shí)拋出此異常。
**ArithmeticException:**算術(shù)運(yùn)算異常。
程序中出現(xiàn)了除以零這樣的運(yùn)算就會(huì)出這樣的異常,對(duì)這種異常,大家就要好好檢查一下自己程序中涉及到數(shù)學(xué)運(yùn)算的地方,公式是不是有不妥了。
**NumberFormatException:**數(shù)字格式異常。
當(dāng)試圖將一個(gè)String轉(zhuǎn)換為指定的數(shù)字類型,而該字符串確不滿足數(shù)字類型要求的格式時(shí),拋出該異常
實(shí)現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢(shì):
適合多個(gè)相同的程序代碼的線程去共享同一個(gè)資源。
可以避免java中的單繼承的局限性。
增加程序的健壯性,實(shí)現(xiàn)解耦操作,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)立。
線程池只能放入實(shí)現(xiàn)Runable或callable類線程,不能直接放入繼承Thread的類。
Java 任務(wù)調(diào)度
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。