JAVA異常、多線程、垃圾回收_第1頁
JAVA異常、多線程、垃圾回收_第2頁
JAVA異常、多線程、垃圾回收_第3頁
JAVA異常、多線程、垃圾回收_第4頁
JAVA異常、多線程、垃圾回收_第5頁
已閱讀5頁,還剩53頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

異常、多線程、垃圾回收主講人:翟佳宇CompanyLogo主要內(nèi)容Java異常處理機(jī)制1多線程編程2垃圾回收機(jī)制3Java代碼優(yōu)化編程4CompanyLogo異?;靖拍町?dāng)出現(xiàn)程序無法控制的外部環(huán)境問題(用戶提供的文件不存在,文件內(nèi)容損壞,網(wǎng)絡(luò)不可用等)時(shí),Java就會(huì)用異常對(duì)象處理。異常的頂層父類:java.lang.Throwable參考實(shí)例:ShowException.javaCompanyLogo異常分類異常分類:檢查性異常java.lang.Exception(編譯異常)運(yùn)行期異常

java.lang.RuntimeException錯(cuò)誤:java.lang.ErrorCompanyLogo異常分類檢查性異常:程序正確,但因?yàn)橥庠诘沫h(huán)境條件不滿足而引發(fā)。例如:用戶錯(cuò)誤及I/O問題---程序試圖打開一個(gè)不存在的遠(yuǎn)程端口或者打開不存在的文件。Java編譯器強(qiáng)制要求處理這類異常,如果不捕獲這類異常,程序講不能被編譯。參考實(shí)例:略CompanyLogo異常分類運(yùn)行異常程序存在bug如數(shù)組越界,0作為被除數(shù),這類異常一般通過程序來避免,Java編譯器強(qiáng)制要求處理這類異常編譯器檢測(cè)不到這類異常,不會(huì)完全排除參考實(shí)例:TypeCheckException.javaCompanyLogo異常分類錯(cuò)誤:一般很少見,也很難通過程序解決。它可能源于程序的bug,更可能源于環(huán)境問題,如內(nèi)存耗盡,程序中無需處理,而由運(yùn)行環(huán)境處理。示例:這個(gè)沒法演示CompanyLogo異常處理方法異常處理方法:處理異常在可能出現(xiàn)異常的地方直接處理異常拋出異常異常拋給函數(shù)調(diào)用者,讓函數(shù)調(diào)用者去處理異常CompanyLogo異常處理方法(一)處理異常try{……}catch{……}finally{……}CompanyLogo異常處理方法(一)try{……}catch{……}在出現(xiàn)異常的地方終止執(zhí)行代碼,進(jìn)入catch語句,如果有多個(gè)catch語句則進(jìn)入匹配異常的catch塊中CompanyLogo異常處理方法(一)finally{……}如果把finally塊置于try…catch語句后,finally塊一般都會(huì)得以執(zhí)行,相當(dāng)于一個(gè)保障,即使前面的try塊發(fā)生異常而沒有處理對(duì)應(yīng)異常的catch塊,finally會(huì)馬上執(zhí)行CompanyLogo異常處理方法(一)關(guān)于finally注意以下情況中,finally塊將不會(huì)被完全執(zhí)行:finally塊中發(fā)生異常程序所在線程死亡在前面代碼中用了System.exit();關(guān)閉CPUCompanyLogo異常處理方法(二)拋出異常將異常拋給函數(shù)調(diào)用者,讓函數(shù)調(diào)用者去處理異常參考實(shí)例:ExceptionThrow.javaCompanyLogo主要內(nèi)容Java異常處理機(jī)制1多線程編程2垃圾回收機(jī)制3Java代碼優(yōu)化編程4CompanyLogo多線程編程線程概念線程→進(jìn)程進(jìn)程:進(jìn)程是指運(yùn)行中的應(yīng)用程序,每個(gè)進(jìn)程都有自己獨(dú)立的地址空間(內(nèi)存空間)CompanyLogo進(jìn)程←→線程計(jì)算機(jī)內(nèi)存空間:進(jìn)程三進(jìn)程二(eclipse)進(jìn)程一(eclipse)線程一線程二線程三……CompanyLogo進(jìn)程←→線程CompanyLogo多線程線程的創(chuàng)建方法通過繼承Thread類,并重寫run函數(shù)實(shí)現(xiàn)Runnable接口并且重寫run函數(shù)示例:創(chuàng)建一個(gè)線程對(duì)象,實(shí)現(xiàn)每隔一秒輸出helloworld并且在執(zhí)行指定次后結(jié)束CompanyLogo多線程為什么提供兩種方法?因?yàn)镴ava是單繼承的,在某些情況下一個(gè)類已經(jīng)繼承了某個(gè)父類,這是再用繼承的方式來創(chuàng)建線程已經(jīng)不可能了,這樣就提出了另外一種方法來創(chuàng)建線程:通過Runnable接口來創(chuàng)建。CompanyLogo多線程兩種方法的區(qū)別本質(zhì)上沒有區(qū)別。但是實(shí)現(xiàn)是有所區(qū)別:通過繼承Thread類實(shí)現(xiàn) Humanhu=newHuman(); //運(yùn)行start函數(shù)后線程進(jìn)入運(yùn)行狀態(tài)(Running) hu.start();通過實(shí)現(xiàn)Runnable接口實(shí)現(xiàn) Human2hu=newHuman2(); ThreadT = newThread(hu); T.start();在編寫程序時(shí),盡量使用接口實(shí)現(xiàn)進(jìn)程類CompanyLogo線程的狀態(tài)關(guān)系創(chuàng)建Runnable(可執(zhí)行狀態(tài))Running(運(yùn)行狀態(tài))Blocked(阻塞狀態(tài))Dead(死亡狀態(tài))出生可以工作參加工作人生發(fā)生意外,失去了工作能力CompanyLogo多線程操作線程的方法線程的休眠Thread.sleep()線程的加入Thread.join()線程的中斷Terrupt()線程的禮讓Thread.yeild()CompanyLogo線程的操作方法(一)線程的休眠sleep(longmillis)Thread類的sleep方法用于讓當(dāng)前線程暫時(shí)休眠一段時(shí)間參數(shù)millis的單位是毫秒示例:略CompanyLogo線程的操作方法(二)線程的加入join()處在“執(zhí)行狀態(tài)”的線程如果調(diào)用了其他線程的join方法,將被掛起進(jìn)入“阻塞狀態(tài)”目標(biāo)線程執(zhí)行完畢后才會(huì)解除阻塞,回到“可執(zhí)行狀態(tài)”例如:A/B是兩個(gè)線程,在線程A中調(diào)用線程B.join(),此時(shí)線程A將被阻塞,直到線程B執(zhí)行完畢舉例:com.bupt.MultiThread.JoinThreadTest.javaCompanyLogo線程的操作方法(三)線程的中斷Interrupt()在線程受到阻塞時(shí)拋出一個(gè)中斷信號(hào),這樣線程就得以退出阻塞的狀態(tài)。更確切的說,如果線程被Object.wait,Thread.join和Thread.sleep三種方法之一阻塞,那么,它將接收到一個(gè)中斷異常(InterruptedException),從而提早地終結(jié)被阻塞狀態(tài)。Terrupt()方法不會(huì)中斷一個(gè)正在運(yùn)行的線程。舉例:com.bupt.MultiThread.InterruptThreadTest.java

CompanyLogo線程的操作方法(四)線程的禮讓yield()它只是給當(dāng)前正處于運(yùn)行狀態(tài)下的線程一個(gè)提醒,告知它可以將資源讓給其他線程,但這只是一種暗示,沒有任何一種機(jī)制保證當(dāng)前線程會(huì)將資源禮讓。使具有相同優(yōu)先級(jí)的線程有機(jī)會(huì)進(jìn)入可執(zhí)行的機(jī)會(huì)。對(duì)支持多任務(wù)的操作系統(tǒng)來說,不需要調(diào)用yield()方法,因?yàn)椴僮飨到y(tǒng)會(huì)為線程自動(dòng)分配CPU時(shí)間來執(zhí)行

CompanyLogo多線程線程同步的引出鐵路賣票系統(tǒng)示例:SellTicketSys.java

CompanyLogo線程同步多線程應(yīng)用程序同時(shí)訪問共享對(duì)象時(shí),由于線程間相互搶占CPU的控制權(quán),造成一個(gè)線程夾在另一個(gè)線程的執(zhí)行過程中運(yùn)行,所以可能導(dǎo)致錯(cuò)誤的執(zhí)行結(jié)果。

CompanyLogo對(duì)象鎖線程同步為了防止共享對(duì)象在并發(fā)訪問時(shí)出現(xiàn)錯(cuò)誤,Java中提供了“synchronized”關(guān)鍵字。synchronized關(guān)鍵字確保共享對(duì)象在同一時(shí)刻只能被一個(gè)線程訪問,這種處理機(jī)制稱為“線程同步”或“線程互斥”。Java中的“線程同步”基于“對(duì)象鎖”的概念CompanyLogo對(duì)象鎖Java對(duì)象鎖示例:CompanyLogo同步方法使用synchronized關(guān)鍵字同步方法被“synchronized”關(guān)鍵字修飾的方法稱為“同步方法”當(dāng)一個(gè)線程訪問對(duì)象的同步方法時(shí),被訪問對(duì)象就處于“鎖定”狀態(tài),訪問該方法的其他線程只能等待

CompanyLogo同步塊使用synchronized關(guān)鍵字同步塊如果只希望同步部分代碼行,可以使用“同步塊”

同步塊的作用與同步方法一樣,只是控制范圍有所區(qū)別

在多線程應(yīng)用程序中,obj代表被鎖定的共享對(duì)象CompanyLogo線程同步正確的售票系統(tǒng)示例:SynchronousSellTicketSys.java

CompanyLogo多線程線程間的通信線程之間的通信使用wait()、notify()、notifyAll()方法實(shí)現(xiàn)

CompanyLogo多線程同步wait()調(diào)用wait()函數(shù)可以讓一個(gè)線程等待某個(gè)條件發(fā)生變化,但是這個(gè)變化不是當(dāng)前線程能夠控制的。Wait()會(huì)在外部等待世界產(chǎn)生變化的時(shí)候把任務(wù)掛起,并且只有在notify()、notifyAll()發(fā)生時(shí)才會(huì)被喚醒并且去檢查所產(chǎn)生的變化。Sleep方法調(diào)用是不釋放鎖,但是wait方法會(huì)釋放鎖,讓其他需求該鎖方法執(zhí)行notify()、notifyAll()從wait狀態(tài)中喚醒線程

CompanyLogo多線程注意只能在同步方法或者同步塊中調(diào)用wait()、notify()、notifyAll(),如果在非同步塊或者同步方法中調(diào)用這些方法,程序能通過編譯,但是運(yùn)行的時(shí)候會(huì)得到j(luò)ava.lang.IllegalMonitorStateException異常。這個(gè)異常的原因就是當(dāng)前線程沒有獲得對(duì)象的鎖,或者說,當(dāng)前調(diào)用的對(duì)象不是鎖對(duì)象。調(diào)用wait(),notify(),notifyAll()的對(duì)象必須是當(dāng)前鎖對(duì)象。常見的毛病就是使用了線程對(duì)象來調(diào)用這些方法CompanyLogo主要內(nèi)容Java異常處理機(jī)制1多線程編程2垃圾回收機(jī)制3Java代碼優(yōu)化編程4CompanyLogo垃圾回收機(jī)制概念GC(GarbageCollection)垃圾回收是Java程序設(shè)計(jì)中內(nèi)存管理的核心概念,JVM的內(nèi)存管理機(jī)制被稱為垃圾回收機(jī)制。一個(gè)對(duì)象創(chuàng)建后被放置在JVM的堆內(nèi)存中,當(dāng)永遠(yuǎn)不再引用這個(gè)對(duì)象時(shí),它將被JVM在堆內(nèi)存中回收。被創(chuàng)建的對(duì)象不能再生,同時(shí)也沒有辦法通過程序語句釋放它們。

CompanyLogo垃圾回收機(jī)制

classnode{ intvalue; nodenext;}…nodep,q;p=newnode();q=newnode();q=p;CompanyLogo垃圾回收機(jī)制GC的基本原理對(duì)于程序員來說,分配對(duì)象使用new關(guān)鍵字;釋放對(duì)象時(shí),只要將對(duì)象所有引用賦值為null,讓程序不能夠再訪問到這個(gè)對(duì)象,我們稱該對(duì)象為"不可達(dá)的".GC將負(fù)責(zé)回收所有"不可達(dá)"對(duì)象的內(nèi)存空間。GC通過確定對(duì)象是否被活動(dòng)對(duì)象引用來確定是否收集該對(duì)象。GC首先要判斷該對(duì)象是否是時(shí)候可以收集。兩種常用的方法引用計(jì)數(shù)對(duì)象引用遍歷

CompanyLogoGC常用收集器(一)引用計(jì)數(shù)收集器原理:引用計(jì)數(shù)是垃圾收集器中的早期策略。在這種方法中,堆中每個(gè)對(duì)象(不是引用)都有一個(gè)引用計(jì)數(shù)。當(dāng)一個(gè)對(duì)象被創(chuàng)建時(shí),且將該對(duì)象分配給一個(gè)變量,該變量計(jì)數(shù)設(shè)置為1。當(dāng)任何其它變量被賦值為這個(gè)對(duì)象的引用時(shí),計(jì)數(shù)加1(a=b,則b引用的對(duì)象+1),但當(dāng)一個(gè)對(duì)象的某個(gè)引用超過了生命周期或者被設(shè)置為一個(gè)新值時(shí),對(duì)象的引用計(jì)數(shù)減1。任何引用計(jì)數(shù)為0的對(duì)象可以被當(dāng)作垃圾收集。當(dāng)一個(gè)對(duì)象被垃圾收集時(shí),它引用的任何對(duì)象計(jì)數(shù)減1。

CompanyLogoGC常用收集器(一)引用計(jì)數(shù)收集器優(yōu)缺點(diǎn)優(yōu)點(diǎn):引用計(jì)數(shù)收集器可以很快的執(zhí)行,交織在程序運(yùn)行中。對(duì)程序不被長(zhǎng)時(shí)間打斷的實(shí)時(shí)環(huán)境比較有利。缺點(diǎn):引用計(jì)數(shù)器增加了程序執(zhí)行的開銷,因?yàn)槊看螌?duì)象賦給新的變量,計(jì)數(shù)器加1,而每次現(xiàn)有對(duì)象出了作用域生,計(jì)數(shù)器減1。CompanyLogoGC常用收集器(二)標(biāo)記-清除收集器原理:這種收集器首先遍歷對(duì)象圖并標(biāo)記可到達(dá)的對(duì)象,然后掃描堆棧以尋找未標(biāo)記對(duì)象并釋放它們的內(nèi)存。這種收集器一般使用單線程工作并停止其他操作。并且,由于它只是清除了那些未標(biāo)記的對(duì)象,而并沒有對(duì)標(biāo)記對(duì)象進(jìn)行壓縮,導(dǎo)致會(huì)產(chǎn)生大量?jī)?nèi)存碎片,從而浪費(fèi)內(nèi)存。注意:只有當(dāng)堆滿的時(shí)候,才開始標(biāo)記-清除過程。首先,遍歷跟蹤運(yùn)行時(shí)棧指向的所有引用,把他們指向的內(nèi)存設(shè)為標(biāo)記。然后檢測(cè)堆塊中沒有標(biāo)記的塊,釋放這些內(nèi)存。

CompanyLogoGC常用收集器(二)標(biāo)記-清除收集器優(yōu)缺點(diǎn)優(yōu)點(diǎn):也許永遠(yuǎn)不需要運(yùn)行跟蹤收集器,因?yàn)橹挥性趆eap滿的時(shí)候才運(yùn)行。跟蹤收集器可以發(fā)現(xiàn)并釋放所有不可用的內(nèi)存缺點(diǎn):GC需要停止其他的活動(dòng)。這種方法意味著所有與應(yīng)用程序相關(guān)的工作停止,只有GC運(yùn)行。在運(yùn)行期間這種不可預(yù)期的中斷也許是某些應(yīng)用不能接受的。

CompanyLogoGC常用收集器(三)復(fù)制收集器原理:這種收集器將堆棧分為兩個(gè)域,常稱為半空間。每次僅使用一半的空間,JVM生成的新對(duì)象則放在另一半空間中。GC運(yùn)行時(shí),它把可到達(dá)對(duì)象復(fù)制到另一半空間,從而壓縮了堆棧。這種方法適用于短生存期的對(duì)象,持續(xù)復(fù)制長(zhǎng)生存期的對(duì)象則導(dǎo)致效率降低。并且對(duì)于指定大小堆來說,需要兩倍大小的內(nèi)存,因?yàn)槿魏螘r(shí)候都只使用其中的一半。

CompanyLogoGC常用收集器(三)復(fù)制收集器優(yōu)缺點(diǎn)優(yōu)點(diǎn):相比于標(biāo)記-清除收集器,復(fù)制收集器較快。缺點(diǎn):只能使用一半的堆空間。

CompanyLogo總結(jié)垃圾收集器的作用Java語言規(guī)范沒有明確地說明JVM使用哪種垃圾回收算法,但是任何一種垃圾回收算法一般要做2件基本的事情:發(fā)現(xiàn)無用信息對(duì)象回收被無用對(duì)象占用的內(nèi)存空間,使該空間可被程序再次使用其他垃圾收集器

CompanyLogo主要內(nèi)容Java異常處理機(jī)制1多線程編程2垃圾回收機(jī)制3Java代碼優(yōu)化編程4CompanyLogoJava優(yōu)化編程盡量復(fù)用對(duì)象例如String對(duì)象的使用中,出現(xiàn)字符串連接情況時(shí)應(yīng)用StringBuffer代替。示例:

Stringa=“hello”;Stringb=“world”;a=a+b;helloworldhelloworldabCompanyLogoJava優(yōu)化編程換作StringBuffer

StringBuffera=“hello”;StringBufferb=“world”;a=a+b;helloworldabhelloworldJava優(yōu)化編程由于JVM的有其自身的GC機(jī)制,不需要程序開發(fā)者的過多考慮,從一定程度上減輕了開發(fā)者負(fù)擔(dān),但同時(shí)也遺漏了隱患,過分的創(chuàng)建對(duì)象會(huì)消耗系統(tǒng)的大量?jī)?nèi)存,嚴(yán)重時(shí)會(huì)導(dǎo)致內(nèi)存泄露,因此,保證過期對(duì)象的及時(shí)回收具有重要意義。JVM回收垃圾的條件是:對(duì)象不在被引用;然而,JVM的GC并非十分的機(jī)智,即使對(duì)象滿足了垃圾回收的條件也不一定會(huì)被立即回收。所以,建議我們?cè)趯?duì)象使用完畢,應(yīng)手動(dòng)置成null。Java優(yōu)化編程盡量減少對(duì)變量的重復(fù)計(jì)算

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論