


下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、1 根底篇1.1 根本功1.1.1 面向?qū)ο筇卣鞣庋b,繼承,多態(tài)和抽象1、封裝 封裝給對象提供了隱藏內(nèi)部特性和行為的能力。 對象提供一些能被其他對象訪問的方法 來改變它內(nèi)部的數(shù)據(jù)。在 Java 當(dāng)中,有 3 種修飾符: public , private 和 protected 。每一種修飾符給其他的位于同一個包或者不同包下面對象賦予了不同的訪 問權(quán)限。下面列出了使用封裝的一些好處:1) 通過隱藏對象的屬性來保護(hù)對象內(nèi)部的狀態(tài)。2) 提高了代碼的可用性和可維護(hù)性,因為對象的行為可以被單獨的改變或者是擴(kuò)展。3) 制止對象之間的不良交互提高模塊化2、繼承 繼承給對象提供了從基類獲取字段和方法的能力。
2、繼承提供了代碼的重用行,也可以在 不修改類的情況下給現(xiàn)存的類添加新特性。3、多態(tài) 多態(tài)是編程語言給不同的底層數(shù)據(jù)類型做一樣的接口展示的一種能力。 一個多態(tài)類型上 的操作可以應(yīng)用到其他類型的值上面。4、抽象 抽象是把想法從具體的實例中別離出來的步驟,因此,要根據(jù)他們的功能而不是實現(xiàn)細(xì) 節(jié)來創(chuàng)立類。 Java 支持創(chuàng)立只暴漏接口而不包含方法實現(xiàn)的抽象的類。這種抽象技術(shù) 的主要目的是把類的行為和實現(xiàn)細(xì)節(jié)別離開。1.1.2 final, finally, finalize的區(qū)別1、final 修飾符關(guān)鍵字如果一個 類被聲明為 final ,意味著它 不能再派生出新的子類 ,不能作為父類被繼承。 因此一
3、個類不能既被聲明為 abstract 的,又被聲明為 final 的。將變量或方法 聲明為 final ,可以保證它們 在使用中不被改變 。被聲明為 final 的 變量 必須在聲明時給定初值 ,而在以后的引用中只能讀取,不可修改。被聲明為 final 的方 法也同樣只能使用,不能重載。2、finally在異常處理時提供 finally 塊來執(zhí)行任何去除操作。如果拋出一個異常,那么相匹配的 catch 子句就會執(zhí)行,然后控制就會進(jìn)入 finally 塊如果有的話 。3、finalize方法名。 Java 技術(shù)允許使用 finalize() 方法在垃圾收集器將對象從內(nèi)存中去除出去 之前做必要的清
4、理工作。 這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個 對象調(diào)用的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統(tǒng)資源或者執(zhí)行其他清理工作。 finalize() 方法是在垃圾收 集器刪除對象之前對這個對象調(diào)用的。2021最新Java面試題整理1.1.3 int 和In teger有什么區(qū)別int是根本數(shù)據(jù)類型,而Integer是其包裝類,注意是一個類。為什么要提供包裝類呢? ?一是為了在各種類型間轉(zhuǎn)化,通過各種方法的調(diào)用。否那么你無法直接通過變量轉(zhuǎn)化。1.1.4 重載和重寫的區(qū)別override重寫1.方法名、參數(shù)、返回值一
5、樣。2.子類方法不能縮小父類方法的訪問權(quán)限。3.子類方法不能拋出比父類方法更多的異常(但子類方法可以不拋出異常 )。4.存在于父類和子類之間。5.方法被定義為final不能被重寫。overload重載1.參數(shù)類型、個數(shù)、順序至少有一個不一樣。2.不能重載只有返回值不冋的方法名。3.存在于父類和子類、冋類中。區(qū)別點重載重寫覆寫英文Overloadi ngOverid ing定義方法名稱一樣,參數(shù)的類型或個數(shù)不方法名稱、參數(shù)類型、返回值類型全部一同樣權(quán)限對權(quán)限沒要求被重與的方法不能擁有更嚴(yán)格的權(quán)限范圍發(fā)生在一個類中發(fā)生在繼承類中1.1.5 抽象類和接口有什么區(qū)別接口是公開的,里面不能有私有的方法或
6、變量 ,是用于讓別人使用的, 而抽象類是可以 有私有方法或私有變量的,另外,實現(xiàn)接口的一定要實現(xiàn)接口里定義的所有方法,而實現(xiàn)抽象類可以有選擇地重寫需要用到的方法 ,一般的應(yīng)用里,最頂級的是接口,然后是抽象類實 現(xiàn)接口,最后才到具體類實現(xiàn)。還有,接口可以實現(xiàn)多重繼承, 而一個類只能繼承一個超類 ,但可以通過繼承多個接口 實現(xiàn)多重繼承,接口還有標(biāo)識里面沒有任何方法,如Remote接口和數(shù)據(jù)共享里面的變量全是常量的作用。1.1.6 說說反射的用途及實現(xiàn)Java反射機制主要提供了以下功能:在運行時構(gòu)造一個類的對象;判斷一個類所具有的成員變量和方法;調(diào)用一個對象的方法;生成動態(tài)代理。反射最大的應(yīng)用就是框
7、架Java反射的主要功能:-確定一個對象的類-取出類的modifiers,數(shù)據(jù)成員,方法,構(gòu)造器,和超類.-找出某個接口里定義的常量和方法說明.- 創(chuàng)立一個類實例 , 這個實例在運行時刻才有名字 ( 運行時間才生成的對象 ).- 取得和設(shè)定對象數(shù)據(jù)成員的值 , 如果數(shù)據(jù)成員名是運行時刻確定的也能做到 .- 在運行時刻調(diào)用動態(tài)對象的方法 .- 創(chuàng)立數(shù)組 , 數(shù)組大小和類型在運行時刻才確定 , 也能更改數(shù)組成員的值 . 反射的應(yīng)用很多,很多框架都有用到spri ng 的ioc/di 也是反射. javaBean和jsp之間調(diào)用也是反射.struts 的 FormBean 和頁面之間也是通過反射調(diào)用
8、.JDBC 的 classForName() 也是反射 .hibernate 的 find(Class clazz) 也是反射.反射還有一個不得不說的問題, 就是性能問題, 大量使用反射系統(tǒng)性能大打折扣。 怎么使用 使你的系統(tǒng)到達(dá)最優(yōu)就看你系統(tǒng)架構(gòu)和綜合使用問題啦,這里就不多說了。來源:1.1.7 說說自定義注解的場景及實現(xiàn)登陸、權(quán)限攔截、日志處理,以及各種 Java 框架,如 Spring , Hibernate ,JUnit 提 到注解就不能不說反射, Java 自定義注解是通過運行時靠反射獲取注解。實際開發(fā)中,例如我們要獲取某個方法的調(diào)用日志,可以通過AOP動態(tài)代理機制給方法添加切面,通
9、過反射來獲取方法包含的注解,如果包含日志注解,就進(jìn)展日志記錄。1.1.8 請求的 GET 與 POST 方式的區(qū)別1、請求數(shù)據(jù)的方式GET請求,請求的數(shù)據(jù)會附加在 URL之后,以?分割URL和傳輸數(shù)據(jù),多個參數(shù)用&連接。 URL的編碼格式采用的是 ASCII編碼,而不是 uniclde,即是說所有的非 ASCII字符都 要編碼之后再傳輸。POST請求會把請求的數(shù)據(jù)放置在請求包的包體中。因此,GET請求的數(shù)據(jù)會暴露在地址欄中,而POST青求那么不會。2、傳輸數(shù)據(jù)的大小在標(biāo)準(zhǔn)中,沒有對URL的長度和傳輸?shù)臄?shù)據(jù)大小進(jìn)展限制。但是在實際開發(fā)過程中,對于GET特定的瀏覽器和效勞器對 URL的長度
10、有限制。因此,在 使用GET請求時,傳 輸數(shù)據(jù)會受到URL長度的限制。對于POST由于不是URL傳值,理論上是不會受限制 的,但是實際上各個效勞器會規(guī)定對POST提交數(shù)據(jù)大小進(jìn)展限制, Apache、IIS都有各自的配置。3、平安性POST的平安性比GET的高。這里的平安是指真正的平安,而不同于上面GET提到的平安方法中的平安,上面提到的平安僅僅是不修改效勞器的數(shù)據(jù)。比方,在進(jìn)展登錄操作, 通過GET請求,用戶名和密碼都會暴露再URL上,因為登錄頁面有可能被瀏覽器緩存以及其他人查看瀏覽器的歷史記錄的原因,此時的用戶名和密碼就很容易被他人拿到了。除此之外,GET請求提交的數(shù)據(jù)還可能會造成 Cro
11、ss-site request frogery 攻擊4、中的GET POST SOAF協(xié)議都是在上運行的1.1.9 Session 與 Cookie 區(qū)別cookie是Web效勞器發(fā)送給瀏覽器的一塊信息。瀏覽器會在本地文件中給每一個 Web效勞器 存儲 cookie 。以后瀏覽器在給特定的 Web 效勞器發(fā)請求的時候,同時會發(fā)送所有為 該效勞器存儲的 cookie 。下面列出了 session 和 cookie 的區(qū)別: 無論客戶端瀏覽器做怎么樣的設(shè)置, session 都應(yīng)該能正常工作。 客戶端可以選擇禁用 cookie ,但是, session 仍然是能夠工作的,因為客戶端無法禁 用效勞端
12、的 session 。1.1.10 JDBC 流程1、加載JDBC驅(qū)動程序:在連接數(shù)據(jù)庫之前,首先要加載想要連接的數(shù)據(jù)庫的驅(qū)動到JVM Java 虛擬機,這通過 java.lang.Class 類的靜態(tài)方法 forName(String className) 實現(xiàn)。例如:/ 加載 MySql 的驅(qū)動類 Class.forName("com.mysql.jdbc.Driver"); 成功加載后,會將 Driver 類的實例注冊到 DriverManager 類中。2、提供JDBC連接的URL-連接URL定義了連接數(shù)據(jù)庫時的協(xié)議、子協(xié)議、數(shù)據(jù)源標(biāo)識。- 書寫形式:協(xié)議:子協(xié)議:
13、數(shù)據(jù)源標(biāo)識協(xié)議:在JDBC中總是以jdbc開場子協(xié)議:是橋連接的驅(qū)動程序或是數(shù)據(jù)庫管理系統(tǒng)名稱。 數(shù)據(jù)源標(biāo)識:標(biāo)記找到數(shù)據(jù)庫來源的地址與連接端口。例如:/MySql 的連接 URL, true 表示使用 Unicode 字符集 , characterEncoding 字符編碼方式。 jdbc:mysql:/localhost:3306/test?useUnicode=true&characterEncoding=gbk;3、創(chuàng)立數(shù)據(jù)庫的連接- 要連接數(shù)據(jù)庫,需要向 java.sql.DriverManager 請求并獲得 Connection 對象, 該對象 就代表一個數(shù)據(jù)庫的連接。-
14、 使用 DriverManager 的 getConnectin(String url , String username , String password )方法傳入指定的欲連接的數(shù)據(jù)庫的路徑、數(shù)據(jù)庫的用戶名和密碼來獲得。例如:/ 連接 MySql 數(shù)據(jù)庫,用戶名和密碼都是 root String url = "jdbc:mysql:/localhost:3306/test"Connection con = DriverManager.getConnection(url, "root","root")4、 創(chuàng)立一個 Stateme
15、nt,要執(zhí)行 SQL語句,必須獲得 java.sql.Statement實例,Statement 實例分為以下 3 種類型:1) 執(zhí)行靜態(tài)SQL語句。通常通過 Statement實例實現(xiàn)。Statement stmt = con.createStatement() ;2) 執(zhí)行動態(tài)SQL語句。通常通過 PreparedStatement 實例實現(xiàn)。 PreparedStatement pstmt = con.prepareStatement(sql) ;3) 執(zhí)行數(shù)據(jù)庫存儲過程。通常通過 CallableStatement 實例實現(xiàn)。CallableStatement cstmt = con.
16、prepareCall(“CALL demoSp(? , ?) ) ;5、執(zhí)行SQL語句提供了三種執(zhí)行 SQL語句的方法:executeQuery 、executeUpdate 和 execute1) ResultSet executeQuery(String sqlString):執(zhí)行查詢數(shù)據(jù)庫的 SQL 語句 ,返回一個結(jié)果集 ResultSet 對象。2) int executeUpdate(String sqlString):用于執(zhí)行 INSERT UPDATE或 DELETE 語句以及 SQL DDL語句,如:CREATE TABLED DROP TABLE?6、7、3) execu
17、te(sqlString): 用于執(zhí)行返回多個結(jié)果集、多個更新計數(shù)或二者組合的 句。處理結(jié)果:1) 執(zhí)行更新返回的是本次操作影響到的記錄數(shù)。2) 執(zhí)行查詢返回的結(jié)果是一個 ResultSet 對象。? ResultSet包含符合SQL語句中條件的所有行,并且它通過一套get方法提供了對這些行中數(shù)據(jù)的訪問列是從左到右編號的,并且從列1 開場。? 使用結(jié)果集 ResultSet 對象的訪問方法獲取數(shù)據(jù): while(rs.next()String name = rs.getString( String pass = rs.getString(1) ; /關(guān)閉JDBC對象操作完成以后要把所有使用的J
18、DBC寸象全都關(guān)閉,以釋放 JDBC資源,關(guān)閉順序和聲明順序相反:1) 關(guān)閉記錄集 rs.close()2) 關(guān)閉聲明 stmt.close()name ) ;此方法比擬高效MVC設(shè)計思想3) 關(guān)閉連接寸象 conn.close()M:Model 模型 V:View 視圖, 比方 JSP 等。, 控制器根據(jù)請求來選擇要處理的業(yè)務(wù)邏輯和要選擇的數(shù)據(jù), 這里可能是進(jìn)展重定向或轉(zhuǎn)發(fā)等 ., 再返回C:Controller 控制器 模型就是封裝業(yè)務(wù)邏輯和數(shù)據(jù)的一個一個的模塊 , 控制器就是調(diào)用這些模塊的 (java 中通常是用 Servlet 來實現(xiàn) , 框架的話很多是用 Struts2 來實現(xiàn)這一層
19、 ), 視圖就主要是你看到的 當(dāng)用戶發(fā)出請求的時候 去把結(jié)果輸出到視圖層1.1.12 equals 與 = 的區(qū)別值類型 int,char,long,boolean 等都是 用 =判斷相等性 。寸象引用的話,=判斷引用所指的寸象是否是同一個。equals 是 Object 的成員函數(shù),有些類會覆蓋 override 這個方法,用于判斷寸象的 等價性。例如String類,兩個引用所指向的Stri ng都是"abc",但可能出現(xiàn)他們實際對應(yīng)的寸象并不是同一個和 jvm 實現(xiàn)方式有關(guān) ,因此用 =判斷他們可能不相等,但用equals判斷一定是相等的。1.2 集合1.2.1 Lis
20、t 和 Set 區(qū)別List,Set 都是繼承自 Collection 接口List 特點: 元素有放入順序,元素可重復(fù)Set 特點: 元素?zé)o放入順序,元素不可重復(fù) ,重復(fù)元素會覆蓋掉注意:元素雖然無放入順序,但是元素在set中的位置是有該元素的HashCode決定的,其位置其實是固定的,參加 Set 的 Object 必須定義 equals() 方法,另外 list 支持 for 循 環(huán),也就是通過下標(biāo)來遍歷,也可以用迭代器,但是 set 只能用迭代,因為他無序,無法用 下標(biāo)來取得想要的值。 Set 和 List 比照:Set : 檢索元素效率低下,刪除和插入效率高 ,插入和刪除不會引起元素
21、位置改變。List :和數(shù)組類似, List 可以動態(tài)增長,查找元素效率高,插入刪除元素效率低 ,因為會 引起其他元素位置改變。1.2.2 List 和 Map 區(qū)別List 是 對象集合,允許對象重復(fù) 。Map是鍵值對的集合,不允許key重復(fù)。1.2.3 Arraylist 與 LinkedList 區(qū)別Arraylist :優(yōu)點: ArrayList 是實現(xiàn)了 基于動態(tài)數(shù)組的數(shù)據(jù)構(gòu)造 ,因為地址連續(xù) ,一旦數(shù)據(jù)存儲好了, 查詢操作效率會比擬高在內(nèi)存里是連著放的 。缺點:因為地址連續(xù), ArrayList 要移動數(shù)據(jù) , 所以插入和刪除操作效率比擬低。LinkedList :優(yōu)點: Link
22、edList 基于鏈表的數(shù)據(jù)構(gòu)造 , 地址是任意的 ,所以在開辟內(nèi)存空間的時候不需要 等一個連續(xù)的地址, 對于新增和刪除操作 add 和 remove , LinedList 比擬占優(yōu)勢。 LinkedList 適用于要頭尾操作或插入指定位置的場景 缺點:因為 LinkedList 要移動指針 , 所以查詢操作性能比擬低。適用場景分析:當(dāng)需要對數(shù)據(jù)進(jìn)展對此訪問的情況下選用 ArrayList ,當(dāng)需要對數(shù)據(jù)進(jìn)展屢次增加刪除修改 時采用 LinkedList 。1.2.4 ArrayList 與 Vector 區(qū)別/ 構(gòu)造一個 初始容量為 10 的空列表public ArrayList()/ 構(gòu)
23、造一個具有指定初始容量的空列表。public ArrayList(int initialCapacity)/ 構(gòu)造一個包含指定 collection 的元素的列表public ArrayList(Collection<?extends E> c)Vector 有四個構(gòu)造方法:/ 使用指定的初始容量和等于零的容量增量構(gòu)造一個空向量public Vector()/ 構(gòu)造一個空向量,使其內(nèi)部數(shù)據(jù)數(shù)組的大小,其標(biāo)準(zhǔn)容量增量為零public Vector(intinitialCapacity)/ 構(gòu)造一個包含指定collection 中的元素的向量public Vector(Collecti
24、on<? extends E> c)/ 使用指定的初始容量和容量增量構(gòu)造一個空的向量capacityIncrement)public Vector(int initialCapacity,intArrayList 和 Vector 都是用數(shù)組實現(xiàn)的,主要有這么三個區(qū)別:Vector 是多線程平安的 ,線程平安就是說多線程訪問同一代碼,不會產(chǎn)生不確定的結(jié)果。而 ArrayList 不是,這個可以從源碼中看出, Vector 類中的方法很多有 synchronized 進(jìn)展 修飾,這樣就導(dǎo)致了 Vector 在效率上無法與 ArrayList 相比 ; 兩個都是采用的線性連續(xù)空間存儲元
25、素, 但是當(dāng)空間缺乏的時候, 兩個類的增加方式是不同。 Vector 可以設(shè)置增長因子,而 ArrayList 不可以。Vector 是一種老的動態(tài)數(shù)組,是線程同步的,效率很低,一般不贊成使用。適用場景分析:Vector 是線程同步的,所以它也是線程平安的,而 ArrayList 是線程異步的,是不平安的 。 如果不考慮到線程的平安因素,一般用 ArrayList 效率比擬高。如果集合中的元素的數(shù)目大于目前集合數(shù)組的長度時,在集合中使用數(shù)據(jù)量比擬大的數(shù)據(jù), 用 Vector 有一定的優(yōu)勢。125 HashMap和 Hashtable 的區(qū)別1. hashMap 去掉了 HashTable 的
26、contains 方法,但是加上了 containsValue 和 containsKey 方法。2. hashTable同步的,而 HashMap是非同步的,效率上逼 hashTable要高。3. hashMap 允許空鍵值,而 hashTable 不允許 。TreeMap:非線程平安基于紅黑樹實現(xiàn)。TreeMap沒有調(diào)優(yōu)選項,因為該樹總處于平衡狀態(tài)。Treemap:適用于按自然順序或自定義順序遍歷鍵(key)。1.2.6 HashSet 和 HashMap 區(qū)別set 是 線性構(gòu)造 , set 中的 值不能重復(fù) , hashset 是 set 的 hash 實現(xiàn), hashset 中值不
27、能重復(fù)是用hashmap的key來實現(xiàn)的。map是鍵值對映射,可以空鍵空值 。HashMap是Map接口的hash實現(xiàn),key的唯一性是 通過 key 值 hash 值的唯一來確定, value 值是那么是鏈表構(gòu)造。他們的共同點都是 hash 算法實現(xiàn)的唯一性,他們都不能持有根本類型,只能持有對象1.2.7 HashMap和 ConcurrentHashMap 的區(qū)別ConcurrentHashMap是線程平安的 HashMap的實現(xiàn)。1ConcurrentHashMap 對整個桶數(shù)組進(jìn)展了分割分段 (Segment) ,然后在每一個分段上都用 lock 鎖進(jìn)展保護(hù),相對于 HashTable
28、 的 syn 關(guān)鍵字鎖的粒度更精細(xì)了一些,并發(fā)性能更 好,而HashMap沒有鎖機制,不是線程平安的。2HashMap的鍵值對允許有 null,但是 ConCurrentHashMap都不允許。1.2.8 HashMap的工作原理及代碼實現(xiàn)簡單地說, HashMap 在底層將 key-value 當(dāng)成一個整體進(jìn)展處理,這個整體就是一個Entry 對象。 HashMap 底層采用一個 Entry 數(shù)組來保存所有的 key-value 對,當(dāng)需要存 儲一個 Entry 對象時,會根據(jù) hash 算法來決定其在數(shù)組中的存儲位置,在根據(jù) equals 方法決定其在該數(shù)組位置上的鏈表中的存儲位置;當(dāng)需要
29、取出一個 Entry時,也會根據(jù) hash算法找到其在數(shù)組中的存儲位置,再根據(jù) equals方法從該位置上的鏈表中取出該Entry。Fail-Fast 機制是java集合(Collection)中的一種錯誤機制。當(dāng)多個線程對同一個集合的內(nèi)容進(jìn)展操作時,就可能會產(chǎn)生fail-fast 事件。例如:當(dāng)某一個線程 A通過iterator去遍歷某集合的過程中,假設(shè)該集合的內(nèi)容被其他線程所改變了;那么線程A訪問集合時,就會拋出Co ncurre ntModificati on Exception異常,產(chǎn)生fail-fast 事件。參考:ihui.github.io/2021 /07/01/Java集合學(xué)
30、習(xí) 1: HashMap的實現(xiàn)原理1.2.9 CorcurrentHashMap的工作原理及代碼實現(xiàn)HashTable里使用的是synchronized 關(guān)鍵字,這其實是對對象加鎖,鎖住的都是對象 整體,當(dāng)Hashtable的大小增加到一定的時候,性能會急劇下降,因為迭代時需要被鎖定很長的時間。ConcurrentHashMap算是對上述問題的優(yōu)化,其構(gòu)造函數(shù)如下,默認(rèn)傳入的是16,0.75,16。public(int initialCapacity,float loadFdctor, xnt uncurrencyLevelif (ioadFactor > 0) 'I initi
31、al匚總匸y < 0 11 concurtencyLevel Q) throw newlArgvinntExcept ion ();if (concurrcyLeve 1 >鞏時concurrencyLevel -/ Find power- of two sizes best matarguitantint 33hi= 0;int ss:se = 1;while ai ze < c on cm rrs n cyLs ve1) + 1 ashiftjssize «= 1;thia,segmentShi ft - 32 - sshi ft;this»aegme
32、ntMask = ssize - 1;if (initialCapacity > MAXIMVMCAPACITY) InitialCapaeity = MAXIM喊CAPACITYint c = initialCapacity / S3iz&it (c * ssize < initialcapacity)+c;int cap -TAELE CAPAC I TYfwhile (cp < c)cap «= 1;/ create sgment and aegmnta0JSeginent<Kj V> &0 -n«w Segr.erLt&
33、lt;Kj V>(loadFaatoi:/ (int) (cap * loadfactor), (HashEntry<Kj V>)new HashEntry(cap;Seqment<K; V> ' ss = (Sf?qnient<K, V> ) new Seqirent' ss i ; tSdwrmdObjECt (弟,5£A5£, sO) ;7c:'jre': wriT gl 開蘇乍二this segments - nn;public V | K keyr V value) Segment<K
34、r V> s;if (value = null七h(yuǎn)row new Nul lPr>j nterExcept i r »ri ();int hash = hash(key)tint j (hash. >» segment-Shift 4 segmentMsk;if ( s = (Segment<KrV>)qetOb ject/ nonvolatile; recheck(segment?,(j « SSHIFT + SBASE) ) = null) / / In ft ph r-Sqni-nta = ensureSegment(j);re
35、turn s.put(key hashf value, false)rConcurrentHashMap弓I入了分割(Segment),上面代碼中的最后一行其實就可以理解為 把一個大的 Map拆分成N個小的HashTable ,在put方法中,會根據(jù)hash(paramK.hashCode() 來決定具體存放進(jìn)哪個Segment,如果查看Segment的put操作,我們會發(fā)現(xiàn)內(nèi)部使用的同步機制是基于lock操作的,這樣就可以對Map的一局部Segment進(jìn)展上鎖,這樣影響的只是將要放入同一個Segment的元素的put操作,保證同步的時候,鎖住的不是整個MapHashTable就是這么做的,相
36、對于HashTable提高了多線程環(huán)境下的性能,因此HashTable已經(jīng)被淘汰了。1.3線程創(chuàng)立線程的方式及實現(xiàn)Java中創(chuàng)立線程主要有三種方式:一、繼承Thread類創(chuàng)立線程類1定義Thread類的子類,并重寫該類的run方法,該run方法的方法體就代表了線程要 完成的任務(wù)。因此把 run()方法稱為執(zhí)行體。2創(chuàng)立Thread子類的實例,即創(chuàng)立了線程對象。3調(diào)用線程對象的start()方法來啟動該線程。二、通過Runnable接口創(chuàng)立線程類1定義runnable接口的實現(xiàn)類,并重寫該接口的run()方法,該run()方法的方法體同樣是該線程的線程執(zhí)行體。2創(chuàng)立Runnable實現(xiàn)類的實例,
37、并依此實例作為 Thread的target來創(chuàng)立Thread對象, 該Thread對象才是真正的線程對象。3調(diào)用線程對象的start()方法來啟動該線程。三、通過 Callable 和Future創(chuàng)立線程1創(chuàng)立Callable接口的實現(xiàn)類,并實現(xiàn)call()方法,該call()方法將作為線程執(zhí)行體, 并且有返回值。2創(chuàng)立Callable 實現(xiàn)類的實例,使用FutureTask類來包裝 Callable 對象,該FutureTask 對象封裝了該Callable對象的call()方法的返回值。3使用FutureTask對象作為Thread對象的target創(chuàng)立并啟動新線程。4調(diào)用FutureTa
38、sk對象的get()方法來獲得子線程執(zhí)行完畢后的返回值public class CalLabieThradTest Impleients Callable<Integer> public static void main (String argg) throws InterruptedxceptlotirExecutionException CallableThreadTest ctt = naw CallableThreadTeat); FutureTask<_ntegsr> ft - new tut-ireTa3k:<Integer> (ctt); Th
39、read t = new Thread (ft, FutnreTask'*); 匕.start ();System.out»printin(nF口導(dǎo)k*+ ft.get();public Integer call() throws Exception int i=0;for (; i < 5/ i+*) System* out * printin (Thread* currentThreacf ( *getName ) + ,T ,r + i); return i;創(chuàng)立線程的三種方式的比照采用實現(xiàn)Runnable、Callable 接口的方式創(chuàng)見多線程時,優(yōu)勢是: 線程
40、類只是實現(xiàn)了Runnable接口或Callable 接口,還可以繼承其他類。在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個一樣線程來處理同一份資源的情況,從而可以將CPU代碼和數(shù)據(jù)分開,形成清晰的模型,較好地表達(dá)了面向?qū)ο蟮乃枷?。劣勢是:編程稍微?fù)雜,如果要訪問當(dāng)前線程,那么必須使用Thread.curre ntThread()方法。使用繼承Thread類的方式創(chuàng)立多線程時優(yōu)勢是:編寫簡單,如果需要訪問當(dāng)前線程,那么無需使用Thread.curre ntThread()方法,直接使用this即可獲得當(dāng)前線程。劣勢是:線程類已經(jīng)繼承了Thread類,所以不能再繼承其他父類
41、。1.3.2 sleep() 、join 、yield 有什么區(qū)別1、sleep()方法在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠暫停執(zhí)行,此操作受到系統(tǒng)計時器和調(diào)度程序精度和準(zhǔn)確性的影響。讓其他線程有時機繼續(xù)執(zhí)行,但它并不釋放對象鎖。也就是如果 有Synchronized同步塊,其他線程仍然不能訪問共享數(shù)據(jù)。注意該方法要捕獲異常比方有兩個線程同時執(zhí)行(沒有Synchronized),一個線程優(yōu)先級為 MAX_PRIORITY另一個 為MIN_PRIORITY如果沒有Sleep()方法,只有高優(yōu)先級的線程執(zhí)行完成后, 低優(yōu)先級的線 程才能執(zhí)行;但當(dāng)高優(yōu)先級的線程 sleep(5000)后,低優(yōu)先
42、級就有時機執(zhí)行了??傊?,sleep()可以使低優(yōu)先級的線程得到執(zhí)行的時機,當(dāng)然也可以讓同優(yōu)先級、高優(yōu)先級 的線程有執(zhí)行的時機。2、yield()方法yield()方法和sleep()方法類似,也不會釋放"鎖標(biāo)志",區(qū)別在于,它沒有參數(shù),即yield()方法只是使當(dāng)前線程重新回到可執(zhí)行狀態(tài),所以執(zhí)行yield()的線程有可能在進(jìn)入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行,另外yield()方法只能使同優(yōu)先級或者高優(yōu)先級的線程得到執(zhí)行時機,這也和 sleep()方法不同。3、join()方法Thread的非靜態(tài)方法join()讓一個線程B “參加"到另外一個線程A的尾部。在A執(zhí)行完
43、畢之前,B不能工作。Thread t = new MyThread();t.start();t.joi n();保證當(dāng)前線程停頓執(zhí)行,直到該線程所參加的線程完成為止。然而,如果它參加的線程沒有 存活,那么當(dāng)前線程不需要停頓。1.3.3 說說 CountDownLatch 原理CountDownLatch是同步工具類之一,可以指定一個計數(shù)值,在并發(fā)環(huán)境下由線程進(jìn)展減1操作,當(dāng)計數(shù)值變?yōu)?0之后,被await方法阻塞的線程將會喚醒,實現(xiàn)線程間的同步。1、構(gòu)造器。構(gòu)造函數(shù)很簡單地傳遞計數(shù)值給Sync,并且設(shè)置了 state 。* Constructs a code 匚ountDownLatch in
44、itialized with the given count»A* param uoun二 the ni-imber oflink frcountQc?vjnJ must be invoked* before threads can pass through await* throws 11 legalArgumentException if fcount ia netjat ive(int count)if |count < 0) throw new IllegalArgumentExceptioncount < this= new Synccoiint);2、阻塞線程
45、。await 方法,直接調(diào)用了 AQS即卩 Sync )的 acquireSharedlnterruptibly public void FBSfCI <) throws InterruptedtKcept ion ( sync. acquireSharedln(I);throws InterruptedException if (Thread.)threw new Interru.ptedExcept丄 if (txyAcquireShared(arg) < 0)ctoAcquirr Shared I w tEiriruFtibLy (門匸 g);首先嘗試獲取共享鎖,實現(xiàn)方式和獨
46、占鎖類似,由CountDownLatch實現(xiàn)判斷邏輯。返回1代表獲取成功,返回-1代表獲取失敗。如果獲取失敗,需要調(diào)用doAcquireSharedI nterruptiblyAcquires in sha匚md interrujjtible mode Rparam arg "the ac<jui_e argumen'tprivate void|(int arg)throws Intt!rruptdExcptiun final Node node = addWAiter(Node.SHARED)? boolean failed = true;try Ifor (;) f
47、inal Node p - node,predecessor(); if (p = headJ int r = tryAcqiiirShard (augi ; if (r >= 0) aetHcadTkridPropaqat (nodet r)丿p>next = null; /; hlp GC failed - false;芒e七uirn;if (shouldParkAfterFailedAquire(p7 node) &在 parkAndCheckInterrupt()throw new I ritprruptsdKxGept; i <»fl ();)fi
48、nally fif (failedcancelAcquire i:node);1doAcquireSharedl nterruptibly的邏輯和獨占功能具體如下:1) 創(chuàng)立的Node是定義成共享的Node.SHARED;2) 被喚醒后重新嘗試獲取鎖,不只設(shè)置自己為head,還需要通知其他等待的線程。重點看后文釋放操作里的setHeadAndPropagate3、釋放操作。countDown操作實際就是釋放鎖的操作,每調(diào)用一次,計數(shù)值減少1。* Decrements the count of the latch, releasing all vaiting threads if 1 the c
49、ount reaches zero *<p>lf iLhe current, count, is greater than zero then it 丄芒 decremented, if the new count in zero then sll waiting threads are re-enabled for thread scheduling purposes<p>If the current connt equals zero then nothing happens.public void cQunDown)sync,releaseShared(1|;*
50、Releases in shared mode Implemented by unblocking one or mere1 threads if link tryReleaaeShared returns true.* param arg the release 日uguinuirt * This value is conveyed to+(01 ink iryRp 1 eaShared b*;t i f? ottiprwii" iwi ntrrprptpri* and can represent anything you 11ke»* 上日turn the value
51、二總turned from glink ItryReleaseShared*/public final boolean rpeaseShared(int arg) if JtryReleaseShared(arg doRelea呂啟占harEti (丨return true;return false;1同樣是首先嘗試釋放鎖,具體實現(xiàn)在CountDownLatch中:死循環(huán)加上cas的方式保證state的減1操作,當(dāng)計數(shù)值等于 0,代表所有子線程都執(zhí)行完 畢,被await阻塞的線程可以喚醒了,下一步調(diào)用doReleaseShared :aignal successor and ensure* R
52、elease action fur shcirecL moae* propagation (Note: For exclusive Tnoder release just amounts* to calling unparkSuccessor of head if it needs sig口ml*)private void()* Ensure that a releaseeven if there are other* in-progress aaquires/release. This proceeds in the 口鬥口耳丄* way of trying to unparkSuocess
53、or of head if it needs* signalv But if it does notf status is 再ct tc PROPAGATE to* ensure that upon rele=sef propagation continues.* Add!t i i inal ly, we must 1 oop in casp anode i.s added* while we are doing th is - Al soj unlike other uses of* unparkSuccessor, we need to know if CAS to reset stat
54、us* fails, if sa rechecking,ford INode h = head;if (h !- null && h !- tail) int wl5 = h.WdiLSLdtu.ii:if (w呂=Node EIGNW if !Node *0)continue;/ loop torecheck eases1unparkSuccessor(h);JFelse if |ws0 機*!aampatWai(h, 0,Node. PROPAGATE)1con 七 imi 目:/ loop onfailed CASJ if (h=/ loop ifhead changed
55、break;標(biāo)記1里,頭節(jié)點狀態(tài)如果 SIGNAL,那么狀態(tài)重置為 0,并調(diào)用unparkSuccessor喚醒下個 節(jié)點。標(biāo)記2里,被喚醒的節(jié)點狀態(tài)會重置成0,在下一次循環(huán)中被設(shè)置成PROPAGAT狀態(tài),代表狀態(tài)要向后傳播。分析CountDownLatch的實現(xiàn)原理什么時候使用 Cou ntDow nLatchJava 并發(fā)編程: CountDownLatch、CyclicBarrier禾口 Semaphore1) CountDownLatch和CyclicBarrier都能夠?qū)崿F(xiàn)線程之間的等待,只不過它們側(cè)重點不同:CountDownLatch 般用于某個線程 A等待假設(shè)干個其他線程執(zhí)行完
56、任務(wù)之后,它才執(zhí) 行;而CyclicBarrier 一般用于一組線程互相等待至某個狀態(tài),然后這一組線程再同時執(zhí)行; 另外,CountDownLatch是不能夠重用的,而 CyclicBarrier是可以重用的。2Semaphore其實和鎖有點類似,它一般用于控制對某組資源的訪問權(quán)限。1.3.4 說說 CyclicBarrier 原理JUC回憶之-CyclicBarrier底層實現(xiàn)和原理135 說說Semaphore原理JAVA多線程-信號量(Semaphore)JUC回憶之-Semaphore底層實現(xiàn)和原理136說說Exchanger原理java.util.c on curre nt.Excha nger應(yīng)用范例與原理淺析137 說說 CountDownLatch 與 CyclicBarrier 區(qū)別Coun tDow nLatchCyclicBarrier減計數(shù)方式加計數(shù)方式計算為0時釋放所有等待的線程計數(shù)到達(dá)指定值時釋放所有等待線程計數(shù)為0時,無法重置計數(shù)到達(dá)指定值時,計數(shù)置為0重新開場調(diào)用cou ntDow n()方法計數(shù)減一,調(diào)用調(diào)用
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國音頻插線板行業(yè)發(fā)展研究報告
- 頭療技術(shù)培訓(xùn)課程體系
- 剖宮產(chǎn)術(shù)前及術(shù)后護(hù)理
- 介入治療病例分析
- 護(hù)理信息化管理提高護(hù)理質(zhì)量
- 2025企業(yè)內(nèi)部培訓(xùn)資料:04 網(wǎng)絡(luò)上10大基本禮儀
- 上海市華東師范大學(xué)第一附屬中學(xué)2022-2023學(xué)年高一上學(xué)期期中考試物理試題
- 安全吹哨題目大全及答案
- spring筆試題目及答案
- ab競賽題目及答案
- 2025年離婚協(xié)議書
- 2025年下半年江蘇連云港灌云縣衛(wèi)生健康委員會所屬事業(yè)單位招聘83人易考易錯模擬試題(共500題)試卷后附參考答案
- 可信數(shù)據(jù)空間解決方案星環(huán)科技
- 硅熱式風(fēng)速傳感器輸出穩(wěn)定性的多維度解析與優(yōu)化策略研究
- 公路養(yǎng)護(hù)安全風(fēng)險辨識
- 2025年人教版小學(xué)一年級下學(xué)期奧林匹克數(shù)學(xué)競賽檢測考試題(附答案解析)
- Brand KPIs for spirits Tito's Handmade Vodka in the United States-外文版培訓(xùn)課件(2025.2)
- 2025屆深圳市高三年級第二次調(diào)研試題講評 課件
- 裝修陪跑合同協(xié)議書模板
- 鄭大毛概期末試題及答案
- 《光生載流子效應(yīng)》課件
評論
0/150
提交評論