1? ?接口的意義:
? ? ? ? ? ? ? ? ? ? ? ? ?規(guī)范、擴(kuò)展、回調(diào)
2 抽象類的意義:
? ? ? ? ? ? ? ? ? ? ? 為其子類提供一個(gè)公共的類型 封裝子類中得重復(fù)內(nèi)容 定義抽象方法夺鲜,子類雖然有不同的實(shí)現(xiàn) 但是定義是一致的
3 父類的靜態(tài)方法能否被子類重寫:
?不能
子類繼承父類后,用相同的靜態(tài)方法和非靜態(tài)方法,這時(shí)非靜態(tài)方法覆蓋父類中的方法(即方法重寫)迁央,父類的該靜態(tài)方法被隱藏(如果對(duì)象是
父類則調(diào)用該隱藏的方法),另外子類可繼承父類的靜態(tài)與非靜態(tài)方法滥崩,至于方法重載我覺得它其中一要素就是在同一類中岖圈,不能說父類中的什
么方法與子類里的什么方法是方法重載的體現(xiàn)
4 內(nèi)部類的作用:
內(nèi)部類可以用多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息钙皮,并且與其他外圍對(duì)象的信息相互獨(dú)立蜂科。
在單個(gè)外圍類中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一個(gè)接口短条,或者繼承同一個(gè)類导匣。
創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻并不依賴于外圍類對(duì)象的創(chuàng)建。
內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系茸时,他就是一個(gè)獨(dú)立的實(shí)體贡定。
內(nèi)部類提供了更好的封裝,除了該外圍類可都,其他類都不能訪問
5 列舉java的集合和繼承關(guān)系:
6 泛型中 extends 和 super 的區(qū)別:
<缓待? extends E>
是 Upper Bound(上限) 的通配符蚓耽,用來限制元素的類型的上限
表示集合中的元素類型上限為E類型,即只能是E或者E的子類
<命斧? super E>
是 Lower Bound(下限) 的通配符 田晚,用來限制元素的類型下限
表示集合中元素類型下限為E類型,即只能是E或E的父類
7 java虛擬機(jī)的特性:
Java語言的一個(gè)非常重要的特點(diǎn)就是與平臺(tái)的無關(guān)性国葬。而使用Java虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵贤徒。一般的高級(jí)語言如果要在不同的平臺(tái)上運(yùn)行,
至少需要編譯成不同的目標(biāo)代碼汇四。而引入Java語言虛擬機(jī)后接奈,Java語言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯。Java語言使用模式Java虛擬機(jī)屏蔽
了與具體平臺(tái)相關(guān)的信息通孽,使得Java語言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼)序宦,就可以在多種平臺(tái)上不加修改地運(yùn)行。
Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí)背苦,把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行互捌。
8 哪些情況下的對(duì)象會(huì)被垃圾回收機(jī)制處理掉:
Java 垃圾回收機(jī)制最基本的做法是分代回收。內(nèi)存中的區(qū)域被劃分成不同的世代行剂,對(duì)象根據(jù)其存活的時(shí)間被保存在對(duì)應(yīng)世代的區(qū)域中秕噪。一般的實(shí)
現(xiàn)是劃分成3個(gè)世代:年輕、年老和永久厚宰。內(nèi)存的分配是發(fā)生在年輕世代中的腌巾。當(dāng)一個(gè)對(duì)象存活時(shí)間足夠長的時(shí)候,它就會(huì)被復(fù)制到年老世代中铲觉。
對(duì)于不同的世代可以使用不同的垃圾回收算法决记。進(jìn)行世代劃分的出發(fā)點(diǎn)是對(duì)應(yīng)用中對(duì)象存活時(shí)間進(jìn)行研究之后得出的統(tǒng)計(jì)規(guī)律游昼。一般來說瞧栗,一個(gè)
應(yīng)用中的大部分對(duì)象的存活時(shí)間都很短僵井。比如局部變量的存活時(shí)間就只在方法的執(zhí)行過程中⊙卧樱基于這一點(diǎn)逗载,對(duì)于年輕世代的垃圾回收算法就可以
很有針對(duì)性。
9 進(jìn)程和線程的區(qū)別:
簡而言之,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程况褪。
線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高更耻。
另外测垛,進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存秧均,從而極大地提高了程序的運(yùn)行效率食侮。
線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的号涯。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口锯七。但是線程不能夠獨(dú)立執(zhí)行链快,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制眉尸。
從邏輯角度來看域蜗,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行噪猾。但操作系統(tǒng)并沒有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用霉祸,來實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別袱蜡。
進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位.
線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源.
一個(gè)線程可以創(chuàng)建和撤銷另一個(gè)線程;同一個(gè)進(jìn)程中的多個(gè)線程之間可以并發(fā)執(zhí)行.
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式丝蹭。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后坪蚁,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響奔穿,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量敏晤,但線程之間沒有單獨(dú)的地址空間贱田,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯茵典,但在進(jìn)程切換時(shí)湘换,耗費(fèi)資源較大,效率要差一些统阿。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作彩倚,只能用線程,不能用進(jìn)程扶平。如果有興趣深入的話帆离,我建議你們看看《現(xiàn)代操作系統(tǒng)》或者《操作系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)》。對(duì)就個(gè)問題說得比較清楚结澄。
10 java中==和equals和hashCode的區(qū)別:
http://blog.csdn.net/tiantiandjava/article/details/46988461
在java中:
==是運(yùn)算符哥谷,用于比較兩個(gè)變量是否相等。
equals麻献,是Objec類的方法们妥,用于比較兩個(gè)對(duì)象是否相等,默認(rèn)Object類的equals方法是比較兩個(gè)對(duì)象的地址勉吻,跟==的結(jié)果一樣
java中的數(shù)據(jù)類型监婶,可分為兩類:
1.基本數(shù)據(jù)類型,也稱原始數(shù)據(jù)類型。byte,short,char,int,long,float,double,boolean
他們之間的比較惑惶,應(yīng)用雙等號(hào)(==),比較的是他們的值煮盼。
2.復(fù)合數(shù)據(jù)類型(類)
當(dāng)他們用(==)進(jìn)行比較的時(shí)候,比較的是他們?cè)趦?nèi)存中的存放地址带污,所以僵控,除非是同一個(gè)new出來的對(duì)象,他們的比較后的結(jié)果為true鱼冀,否則比較后結(jié)果為false报破。 JAVA當(dāng)中所有的類都是繼承于Object這個(gè)基類的,在Object中的基類中定義了一個(gè)equals的方法雷绢,這個(gè)方法的初始行為是比較對(duì)象的內(nèi)存地 址泛烙,但在一些類庫當(dāng)中這個(gè)方法被覆蓋掉了,如String,Integer,Date在這些類當(dāng)中equals有其自身的實(shí)現(xiàn)翘紊,而不再是比較類在堆內(nèi)存中的存放地址了蔽氨。
對(duì)于復(fù)合數(shù)據(jù)類型之間進(jìn)行equals比較,在沒有覆寫equals方法的情況下帆疟,他們之間的比較還是基于他們?cè)趦?nèi)存中的存放位置的地址值的鹉究,因?yàn)镺bject的equals方法也是用雙等號(hào)(==)進(jìn)行比較的,所以比較后的結(jié)果跟雙等號(hào)(==)的結(jié)果相同踪宠。
11 HashMap的實(shí)現(xiàn)原理:
HashMap概述: HashMap是基于哈希表的Map接口的非同步實(shí)現(xiàn)自赔。此實(shí)現(xiàn)提供所有可選的映射操作,并允許使用null值和null鍵柳琢。此類不保證映射的順序绍妨,特別是它不保證該順序恒久不變。
HashMap的數(shù)據(jù)結(jié)構(gòu): 在java編程語言中柬脸,最基本的結(jié)構(gòu)就是兩種他去,一個(gè)是數(shù)組,另外一個(gè)是模擬指針(引用)倒堕,所有的數(shù)據(jù)結(jié)構(gòu)都可以用這兩個(gè)基本結(jié)構(gòu)來構(gòu)造的灾测,HashMap也不例外。HashMap實(shí)際上是一個(gè)“鏈表散列”的數(shù)據(jù)結(jié)構(gòu)垦巴,即數(shù)組和鏈表的結(jié)合體媳搪。
從上圖中可以看出,HashMap底層就是一個(gè)數(shù)組結(jié)構(gòu)骤宣,數(shù)組中的每一項(xiàng)又是一個(gè)鏈表秦爆。當(dāng)新建一個(gè)HashMap的時(shí)候,就會(huì)初始化一個(gè)數(shù)組憔披。
12 java狀態(tài)機(jī):
http://www.jdon.com/designpatterns/designpattern_State.htm
13 int-char-long各占多少字節(jié)數(shù):
byte 位數(shù) 8 字節(jié)數(shù) 1
short 16 2
int 32 4
long 64 8
float 32 4
double 64 8
char 16 2
14 java int與integer的區(qū)別:
http://www.cnblogs.com/shenliang123/archive/2011/10/27/2226903.html
15 string-stringbuffer-stringbuilder區(qū)別:
String 字符串常量
StringBuffer 字符串變量(線程安全)
StringBuilder 字符串變量(非線程安全)
簡要的說等限, String 類型和 StringBuffer 類型的主要性能區(qū)別其實(shí)在于 String 是不可變的對(duì)象, 因此在每次對(duì) String 類型進(jìn)行改變的時(shí)候其實(shí)都等同于生成了一個(gè)新的 String 對(duì)象,然后將指針指向新的 String 對(duì)象,所以經(jīng)常改變內(nèi)容的字符串最好不要用String 精刷,因?yàn)槊看紊蓪?duì)象都會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響,特別當(dāng)內(nèi)存中無引用對(duì)象多了以后,JVM 的 GC 就會(huì)開始工作蔗候,那速度是一定會(huì)相當(dāng)慢的怒允。
而如果是使用 StringBuffer 類則結(jié)果就不一樣了,每次結(jié)果都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作锈遥,而不是生成新的對(duì)象纫事,再改變對(duì)象引用。所以在一般情況下我們推薦使用 StringBuffer 所灸,特別是字符串對(duì)象經(jīng)常改變的情況下丽惶。而在某些特別情況下, String 對(duì)象的字符串拼接其實(shí)是被 JVM 解釋成了 StringBuffer 對(duì)象的拼接爬立,所以這些時(shí)候 String 對(duì)象的速度并不會(huì)比 StringBuffer 對(duì)象慢钾唬,而特別是以下的字符串對(duì)象生成中, String 效率是遠(yuǎn)要比 StringBuffer 快的:
String S1 ="This is only a"+"simple"+" test";StringBuffer Sb =newStringBuffer("This is only a").append("simple").append("test");
你會(huì)很驚訝的發(fā)現(xiàn)侠驯,生成 String S1 對(duì)象的速度簡直太快了抡秆,而這個(gè)時(shí)候 StringBuffer 居然速度上根本一點(diǎn)都不占優(yōu)勢(shì)。其實(shí)這是 JVM 的一個(gè)把戲吟策,在 JVM 眼里儒士,這個(gè) String S1 = “This is only a” + “ simple” + “test”; 其實(shí)就是: String S1 = “This is only a simple test”; 所以當(dāng)然不需要太多的時(shí)間了。但大家這里要注意的是檩坚,如果你的字符串是來自另外的 String 對(duì)象的話着撩,速度就沒那么快了,譬如: String S2 = “This is only a”; String S3 = “ simple”; String S4 = “ test”; String S1 = S2 +S3 + S4; 這時(shí)候 JVM 會(huì)規(guī)規(guī)矩矩的按照原來的方式去做
在大部分情況下 StringBuffer > String
StringBuffer
Java.lang.StringBuffer線程安全的可變字符序列匾委。一個(gè)類似于 String 的字符串緩沖區(qū)拖叙,但不能修改。雖然在任意時(shí)間點(diǎn)上它都包含某種特定的字符序列剩檀,但通過某些方法調(diào)用可以改變?cè)撔蛄械拈L度和內(nèi)容憋沿。
可將字符串緩沖區(qū)安全地用于多個(gè)線程』铮可以在必要時(shí)對(duì)這些方法進(jìn)行同步辐啄,因此任意特定實(shí)例上的所有操作就好像是以串行順序發(fā)生的,該順序與所涉及的每個(gè)線程進(jìn)行的方法調(diào)用順序一致运嗜。
StringBuffer 上的主要操作是 append 和 insert 方法壶辜,可重載這些方法,以接受任意類型的數(shù)據(jù)担租。每個(gè)方法都能有效地將給定的數(shù)據(jù)轉(zhuǎn)換成字符串砸民,然后將該字符串的字符追加或插入到字符串緩沖區(qū)中。append 方法始終將這些字符添加到緩沖區(qū)的末端;而 insert 方法則在指定的點(diǎn)添加字符岭参。
例如反惕,如果 z 引用一個(gè)當(dāng)前內(nèi)容是“start”的字符串緩沖區(qū)對(duì)象,則此方法調(diào)用 z.append("le") 會(huì)使字符串緩沖區(qū)包含“startle”演侯,而 z.insert(4, "le") 將更改字符串緩沖區(qū)姿染,使之包含“starlet”。
在大部分情況下 StringBuilder > StringBuffer
java.lang.StringBuilder
java.lang.StringBuilder一個(gè)可變的字符序列是5.0新增的秒际。此類提供一個(gè)與 StringBuffer 兼容的 API悬赏,但不保證同步。該類被設(shè)計(jì)用作 StringBuffer 的一個(gè)簡易替換娄徊,用在字符串緩沖區(qū)被單個(gè)線程使用的時(shí)候(這種情況很普遍)闽颇。如果可能,建議優(yōu)先采用該類寄锐,因?yàn)樵诖蠖鄶?shù)實(shí)現(xiàn)中兵多,它比 StringBuffer 要快。兩者的方法基本相同
16 java多態(tài):
Java多態(tài)性理解
Java中多態(tài)性的實(shí)現(xiàn)
什么是多態(tài)
面向?qū)ο蟮娜筇匦裕悍庋b橄仆、繼承中鼠、多態(tài)。從一定角度來看沿癞,封裝和繼承幾乎都是為多態(tài)而準(zhǔn)備的援雇。這是我們最后一個(gè)概念,也是最重要的知識(shí)點(diǎn)椎扬。
多態(tài)的定義:指允許不同類的對(duì)象對(duì)同一消息做出響應(yīng)惫搏。即同一消息可以根據(jù)發(fā)送對(duì)象的不同而采用多種不同的行為方式。(發(fā)送消息就是函數(shù)調(diào)用)
實(shí)現(xiàn)多態(tài)的技術(shù)稱為:動(dòng)態(tài)綁定(dynamic binding)蚕涤,是指在執(zhí)行期間判斷所引用對(duì)象的實(shí) 際類型筐赔,根據(jù)其實(shí)際的類型調(diào)用其相應(yīng)的方法。
多態(tài)的作用:消除類型之間的耦合關(guān)系揖铜。
現(xiàn)實(shí)中茴丰,關(guān)于多態(tài)的例子不勝枚舉。比方說按下 F1 鍵這個(gè)動(dòng)作天吓,如果當(dāng)前在 Flash 界面下彈出的就是 AS 3 的幫助文檔贿肩;如果當(dāng)前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持龄寞。同一個(gè)事件發(fā)生在不同的對(duì)象上會(huì)產(chǎn)生不同的結(jié)果汰规。 下面是多態(tài)存在的三個(gè)必要條件,要求大家做夢(mèng)時(shí)都能背出來物邑!
多態(tài)存在的三個(gè)必要條件 一溜哮、要有繼承滔金; 二、要有重寫茂嗓; 三餐茵、父類引用指向子類對(duì)象。
多態(tài)的好處:
1.可替換性(substitutability)述吸。多態(tài)對(duì)已存在代碼具有可替換性钟病。例如,多態(tài)對(duì)圓Circle類工作刚梭,對(duì)其他任何圓形幾何體,如圓環(huán)票唆,也同樣工作朴读。
2.可擴(kuò)充性(extensibility)。多態(tài)對(duì)代碼具有可擴(kuò)充性走趋。增加新的子類不影響已存在類的多態(tài)性衅金、繼承性,以及其他特性的運(yùn)行和操作簿煌。實(shí)際上新加子類更容易獲得多態(tài)功能氮唯。例如,在實(shí)現(xiàn)了圓錐姨伟、半圓錐以及半球體的多態(tài)基礎(chǔ)上惩琉,很容易增添球體類的多態(tài)性。
3.接口性(interface-ability)夺荒。多態(tài)是超類通過方法簽名瞒渠,向子類提供了一個(gè)共同接口,由子類來完善或者覆蓋它而實(shí)現(xiàn)的技扼。如圖8.3 所示伍玖。圖中超類Shape規(guī)定了兩個(gè)實(shí)現(xiàn)多態(tài)的接口方法,computeArea()以及computeVolume()剿吻。子類窍箍,如Circle和Sphere為了實(shí)現(xiàn)多態(tài),完善或者覆蓋這兩個(gè)接口方法丽旅。
4.靈活性(flexibility)椰棘。它在應(yīng)用中體現(xiàn)了靈活多樣的操作,提高了使用效率榄笙。
5.簡化性(simplicity)晰搀。多態(tài)簡化對(duì)應(yīng)用軟件的代碼編寫和修改過程,尤其在處理大量對(duì)象的運(yùn)算和操作時(shí)办斑,這個(gè)特點(diǎn)尤為突出和重要外恕。
Java中多態(tài)的實(shí)現(xiàn)方式:接口實(shí)現(xiàn)杆逗,繼承父類進(jìn)行方法重寫,同一個(gè)類中進(jìn)行方法重載鳞疲。
17 什么導(dǎo)致線程阻塞:
線程的阻塞
為了解決對(duì)共享存儲(chǔ)區(qū)的訪問沖突罪郊,Java 引入了同步機(jī)制,現(xiàn)在讓我們來考察多個(gè)線程對(duì)共享資源的訪問尚洽,顯然同步機(jī)制已經(jīng)不夠了悔橄,因?yàn)樵谌我鈺r(shí)刻所要求的資源不一定已經(jīng)準(zhǔn)備好了被訪問,反過來腺毫,同一時(shí)刻準(zhǔn)備好了的資源也可能不止一個(gè)癣疟。為了解決這種情況下的訪問控制問題,Java 引入了對(duì)阻塞機(jī)制的支持.
阻塞指的是暫停一個(gè)線程的執(zhí)行以等待某個(gè)條件發(fā)生(如某資源就緒)潮酒,學(xué)過操作系統(tǒng)的同學(xué)對(duì)它一定已經(jīng)很熟悉了睛挚。Java 提供了大量方法來支持阻塞,下面讓我們逐一分析急黎。
sleep() 方法:sleep() 允許 指定以毫秒為單位的一段時(shí)間作為參數(shù)扎狱,它使得線程在指定的時(shí)間內(nèi)進(jìn)入阻塞狀態(tài),不能得到CPU 時(shí)間勃教,指定的時(shí)間一過淤击,線程重新進(jìn)入可執(zhí)行狀態(tài)。 典型地故源,sleep() 被用在等待某個(gè)資源就緒的情形:測(cè)試發(fā)現(xiàn)條件不滿足后污抬,讓線程阻塞一段時(shí)間后重新測(cè)試,直到條件滿足為止绳军。
suspend() 和 resume() 方法:兩個(gè)方法配套使用壕吹,suspend()使得線程進(jìn)入阻塞狀態(tài),并且不會(huì)自動(dòng)恢復(fù)删铃,必須其對(duì)應(yīng)的resume() 被調(diào)用耳贬,才能使得線程重新進(jìn)入可執(zhí)行狀態(tài)。典型地猎唁,suspend() 和 resume() 被用在等待另一個(gè)線程產(chǎn)生的結(jié)果的情形:測(cè)試發(fā)現(xiàn)結(jié)果還沒有產(chǎn)生后咒劲,讓線程阻塞,另一個(gè)線程產(chǎn)生了結(jié)果后诫隅,調(diào)用 resume() 使其恢復(fù)腐魂。
yield() 方法:yield() 使得線程放棄當(dāng)前分得的 CPU 時(shí)間,但是不使線程阻塞逐纬,即線程仍處于可執(zhí)行狀態(tài)蛔屹,隨時(shí)可能再次分得 CPU 時(shí)間。調(diào)用 yield() 的效果等價(jià)于調(diào)度程序認(rèn)為該線程已執(zhí)行了足夠的時(shí)間從而轉(zhuǎn)到另一個(gè)線程.
wait() 和 notify() 方法:兩個(gè)方法配套使用豁生,wait() 使得線程進(jìn)入阻塞狀態(tài)兔毒,它有兩種形式漫贞,一種允許 指定以毫秒為單位的一段時(shí)間作為參數(shù),另一種沒有參數(shù)育叁,前者當(dāng)對(duì)應(yīng)的 notify() 被調(diào)用或者超出指定時(shí)間時(shí)線程重新進(jìn)入可執(zhí)行狀態(tài)迅脐,后者則必須對(duì)應(yīng)的 notify() 被調(diào)用.
初看起來它們與 suspend() 和 resume() 方法對(duì)沒有什么分別,但是事實(shí)上它們是截然不同的豪嗽。區(qū)別的核心在于谴蔑,前面敘述的所有方法,阻塞時(shí)都不會(huì)釋放占用的鎖(如果占用了的話)龟梦,而這一對(duì)方法則相反隐锭。
上述的核心區(qū)別導(dǎo)致了一系列的細(xì)節(jié)上的區(qū)別。
首先计贰,前面敘述的所有方法都隸屬于 Thread 類钦睡,但是這一對(duì)卻直接隸屬于 Object 類,也就是說蹦玫,所有對(duì)象都擁有這一對(duì)方法。初看起來這十分不可思議刘绣,但是實(shí)際上卻是很自然的樱溉,因?yàn)檫@一對(duì)方法阻塞時(shí)要釋放占用的鎖,而鎖是任何對(duì)象都具有的纬凤,調(diào)用任意對(duì)象的 wait() 方法導(dǎo)致線程阻塞福贞,并且該對(duì)象上的鎖被釋放。而調(diào)用 任意對(duì)象的notify()方法則導(dǎo)致因調(diào)用該對(duì)象的 wait() 方法而阻塞的線程中隨機(jī)選擇的一個(gè)解除阻塞(但要等到獲得鎖后才真正可執(zhí)行)停士。
其次挖帘,前面敘述的所有方法都可在任何位置調(diào)用,但是這一對(duì)方法卻必須在 synchronized 方法或塊中調(diào)用恋技,理由也很簡單拇舀,只有在synchronized 方法或塊中當(dāng)前線程才占有鎖,才有鎖可以釋放蜻底。同樣的道理骄崩,調(diào)用這一對(duì)方法的對(duì)象上的鎖必須為當(dāng)前線程所擁有,這樣才有鎖可以釋放薄辅。因此要拂,這一對(duì)方法調(diào)用必須放置在這樣的 synchronized 方法或塊中,該方法或塊的上鎖對(duì)象就是調(diào)用這一對(duì)方法的對(duì)象站楚。若不滿足這一條件脱惰,則程序雖然仍能編譯,但在運(yùn)行時(shí)會(huì)出現(xiàn)IllegalMonitorStateException 異常窿春。
wait() 和 notify() 方法的上述特性決定了它們經(jīng)常和synchronized 方法或塊一起使用拉一,將它們和操作系統(tǒng)的進(jìn)程間通信機(jī)制作一個(gè)比較就會(huì)發(fā)現(xiàn)它們的相似性:synchronized方法或塊提供了類似于操作系統(tǒng)原語的功能采盒,它們的執(zhí)行不會(huì)受到多線程機(jī)制的干擾,而這一對(duì)方法則相當(dāng)于 block 和wakeup 原語(這一對(duì)方法均聲明為 synchronized)舅踪。它們的結(jié)合使得我們可以實(shí)現(xiàn)操作系統(tǒng)上一系列精妙的進(jìn)程間通信的算法(如信號(hào)量算法)纽甘,并用于解決各種復(fù)雜的線程間通信問題。
關(guān)于 wait() 和 notify() 方法最后再說明兩點(diǎn):
第一:調(diào)用 notify() 方法導(dǎo)致解除阻塞的線程是從因調(diào)用該對(duì)象的 wait() 方法而阻塞的線程中隨機(jī)選取的抽碌,我們無法預(yù)料哪一個(gè)線程將會(huì)被選擇悍赢,所以編程時(shí)要特別小心,避免因這種不確定性而產(chǎn)生問題货徙。
第二:除了 notify()左权,還有一個(gè)方法 notifyAll() 也可起到類似作用,唯一的區(qū)別在于痴颊,調(diào)用 notifyAll() 方法將把因調(diào)用該對(duì)象的 wait() 方法而阻塞的所有線程一次性全部解除阻塞赏迟。當(dāng)然,只有獲得鎖的那一個(gè)線程才能進(jìn)入可執(zhí)行狀態(tài)蠢棱。
談到阻塞锌杀,就不能不談一談死鎖,略一分析就能發(fā)現(xiàn)泻仙,suspend() 方法和不指定超時(shí)期限的 wait() 方法的調(diào)用都可能產(chǎn)生死鎖糕再。遺憾的是,Java 并不在語言級(jí)別上支持死鎖的避免玉转,我們?cè)诰幊讨斜仨毿⌒牡乇苊馑梨i突想。
以上我們對(duì) Java 中實(shí)現(xiàn)線程阻塞的各種方法作了一番分析,我們重點(diǎn)分析了 wait() 和 notify() 方法究抓,因?yàn)樗鼈兊墓δ茏顝?qiáng)大猾担,使用也最靈活,但是這也導(dǎo)致了它們的效率較低刺下,較容易出錯(cuò)绑嘹。實(shí)際使用中我們應(yīng)該靈活使用各種方法,以便更好地達(dá)到我們的目的橘茉。
18 多線程同步機(jī)制:
http://www.cnblogs.com/gavin110-lgy/p/5716421.html
19 抽象類接口區(qū)別:
1 默認(rèn)的方法實(shí)現(xiàn) 抽象類可以有默認(rèn)的方法實(shí)現(xiàn)完全是抽象的圾叼。接口根本不存在方法的實(shí)現(xiàn)
2 實(shí)現(xiàn) 子類使用extends關(guān)鍵字來繼承抽象類。如果子類不是抽象類的話捺癞,它需要提供抽象類中所有聲明的方法的實(shí)現(xiàn)夷蚊。
? 子類使用關(guān)鍵字implements來實(shí)現(xiàn)接口。它需要提供接口中所有聲明的方法的實(shí)現(xiàn)
3 構(gòu)造器
? ?抽象類可以有構(gòu)造器
? ?接口不能有構(gòu)造器
4 與正常Java類的區(qū)別
? ?除了你不能實(shí)例化抽象類之外髓介,它和普通Java類沒有任何區(qū) 接口是完全不同的類型
5 訪問修飾符
? ?抽象方法可以有public惕鼓、protected和default這些修飾符 接口方法默認(rèn)修飾符是public。你不可以使用其它修飾符唐础。
? ?main方法
? ? 抽象方法可以有main方法并且我們可以運(yùn)行它
? ? 接口沒有main方法箱歧,因此我們不能運(yùn)行它矾飞。
6 多繼承
? ?抽象類在java語言中所表示的是一種繼承關(guān)系,一個(gè)子類只能存在一個(gè)父類呀邢,但是可以存在多個(gè)接口洒沦。
7 速度
? ?它比接口速度要快
? ?接口是稍微有點(diǎn)慢的,因?yàn)樗枰獣r(shí)間去尋找在類中實(shí)現(xiàn)的方法价淌。
8 添加新方法
? ?如果你往抽象類中添加新的方法申眼,你可以給它提供默認(rèn)的實(shí)現(xiàn)。因此你不需要改變你現(xiàn)在的代碼蝉衣。
? ?如果你往接口中添加方法括尸,那么你必須改變實(shí)現(xiàn)該接口的類。
20 容器類之間的區(qū)別:
http://www.cnblogs.com/yuanermen/archive/2009/08/05/1539917.html
http://alexyyek.github.io/2015/04/06/Collection/
http://tianmaying.com/tutorial/java_collection
21 內(nèi)部類:
http://www.cnblogs.com/chenssy/p/3388487.html
22 hashmap和hashtable的區(qū)別:
http://www.233.com/ncre2/JAVA/jichu/20100717/084230917.html