Java結構分析與線程併發庫

  1.集合繼承體系

  用來存儲不同類型的對象(基本數據類型除外),存儲長度可變。Java集合中實際存放的只是對象的引用,

  每個集合元素都是一個引用變量,實際內容都放在堆內存或者方法區裏面,

  但是基本數據類型是在棧內存上分配空間的,棧上的數據隨時就會被收回的。

  2.hashMap和HashSet的區別?

  HashMap實現了Map接口,HashMap儲存鍵值對,使用put()方法將元素放入map中,

  HashSet實現了Set接口,HashSet僅僅存儲對象,使用add()方法將元素放入set中,

  3.List與Set區別?

  相同點:

  都是接口,用來存儲對象

  不同點:

  list是有序可重複的,可以插入null值 常用實現類有ArrayList、LinkedList 和 Vector

  Set是無序不可重複的,只能插入一個null值 常用實現類有 HashSet、LinkedHashSet 以及TreeSet

  4.ArrayList與LinkedList區別?

  相同點:

  他們都是實現的list接口,可以存儲多個數據,任意類型

  不同點:

  ArrayList底層基於數組,數組具有索引,所以查詢快,添加數據慢,因爲他要new一個新數組

  LinkedList底層基於雙向鏈表,由於查詢要重頭開始,所以查詢慢,添加時只需要加一個節點,

  所以添加快

  5.TreeSet與Hashset區別?

  相同點:

  實現的set接口,可以存儲多個數據,任意類型

  不同點:

  TreeSet去重主要是定製排序或自然排序

  自然排序 實體類實現了comparable接口

  定製排序 set容器中需要傳入一個Comparator接口的實現類

  HashSet去重主要通過hashcode和equals方法一起去重

  6.HashMap Hashtable ConcurrentHashMap Properties區別?

  相同點:

  都是實現的map接口,鍵值對方式存儲值

  不同點:

  HashMap線程不安全,可以以null作爲鍵或值 效率較高

  Hashtable 線程安全 ,不可以以null作爲鍵或值 效率較低

  ConcurrentHashMap ,線程安全,不可以以null作爲鍵或值,效率相對較高

  Properties= Hashtable 。

  7.HashMap put get過程

  put方法調用:

  1.調用hash函數得到key的HashCode值

  2.通過HashCode值與數組長度-1邏輯與運算得到一個index值

  3.遍歷索引位置對應的鏈表,如果Entry對象的hash值與hash函數得到的hash值相等,

  並且該Entry對象的key值與put方法傳過來的key值相等則,將該Entry對象的value值賦給一個變量,

  將該Entry對象的value值重新設置爲put方法傳過來的value值。將舊的value返回。

  4.添加Entry對象到相應的索引位置

  get方法調用

  1.當調用get方法時會調用hash函數,這個hash函數會將key的hashCode值返回,返回的hashCode與Entry數

  組長度-1進行邏輯與運算得到一個index值,用這個index值來確定數據存儲在Entry數組當中的位置

  2.通過循環來遍歷索引位置對應的鏈表,初始值爲數據存儲在Entry數組當中的位置,循環條件爲Entry對象不爲null,

  改變循環條件爲Entry對象的下一個節點

  3.如果hash函數得到的hash值與Entry對象當中key的hash值相等,並且Entry對象當中的key值與get方法傳進

  來的key值equals相同則返回該Entry對象的value值,否則返回null

  8.線程的創建方式?

  主要有三種方式:

  1.繼承Thread實現的線程類

  需要創建不同Thread對象,自然不共享

  2.通過Runnable接口創建線程類

  該方法需要先 定義一個類實現Runnable接口,並重寫該接口的 run() 方法,此run方法是線程執行體。接着創建 Runnable實現類的對象,

  作爲創建Thread對象的參數target,此Thread對象纔是真正的線程對象。通過實現Runnable接口的線程類,是互相共享資源的。

  3.使用Callable和Future創建線程

  引入 Future接口,此接口可以接受call() 的返回值,RunnableFuture接口是Future接口和Runnable接口的子接口,

  可以作爲Thread對象的target 。並且, Future 接口提供了一個實現類:FutureTask 。

  9.線程的狀態有哪些 線程中的方法有哪些?

  1.狀態:

  新建狀態:使用 new 關鍵字和 Thread 類或其子類建立一個線程對象後

  就緒狀態: 當線程對象調用了start()方法之後,該線程就進入就緒狀態

  運行狀態: 就緒狀態獲取CPU資源,就可以執行run方法 就是運行狀態

  阻塞狀態:如果一個線程執行了sleep(睡眠)、suspend(掛起)等方法,失去所佔用資源之後,該線程就從運行狀態進入阻塞狀態

  三種阻塞狀態:鄭州婦科醫院 http://www.ytsgfk120.com/

  等待阻塞:運行狀態中的線程執行 wait() 方法,使線程進入到等待阻塞狀態。

  同步阻塞:線程在獲取 synchronized 同步鎖失敗

  其他阻塞:通過調用線程的 sleep() 或 join() 發出了 I/O 請求時,線程就會進入到阻塞狀態或其他

  死亡狀態: 一個運行狀態的線程完成任務或者其他終止條件發生時,該線程就切換到終止狀態。

  2.方法:

  yield方法:使當前線程從執行狀態變爲就緒狀態。

  sleep方法:強制當前正在執行的線程休眠,當睡眠時間到期,則返回到可運行狀態。不會放棄鎖資源

  join方法:通常用於在main()主線程內,等待其它線程完成再結束main()主線程,不會放棄鎖資源

  deamon:

  守護線程(deamon)是程序運行時在後臺提供服務的線程,並不屬於程序中不可或缺的部分。

  當所有非後臺線程結束時,程序也就終止,同時會殺死所有後臺線程。

  main() 屬於非後臺線程。

  使用 setDaemon() 方法將一個線程設置爲後臺線程。

  10.線程安全問題 如何解決

  1.使用synchronized和Lock都可以實現代碼的同步

  2.使用數據庫的樂觀鎖機制,即就是在對共享數據進行操作是先查出數據的版本號再去做

  3.使用數據庫的悲觀鎖機制,即利用數據庫的行鎖或者是表鎖來解決線程安全問題

  4.使用隊列進行排隊處理操作,使用actvicemq、rabbitmq等工具,排隊操作

  5.Zookeeper實現分佈式鎖。簡單來說就是利用Zookeeper的節點是否被佔用的機制來判斷此代碼是否可以運行操作

  11.ThreadLocal有什麼作用 原理

  作用:

  是解決線程問題的一個很好地思路,通過爲每個線程提供一個獨立的變量副本解決了變量併發訪問的衝突問題

  ThreadLocal比直接使用synchronized同步機制解決線程安全

  原理:

  ThreadLocal提供線程局部變量。這些變量與普通的變量不同之處在於,

  每個訪問這種變量的線程(通過它的get或set方法)都有自己的、獨立初始化的變量副本。

  12.wait與sleep區別

  相同點:

  它們都可以使線程暫停

  不同點:

  sleep()方法是Thread類的靜態方法,是線程用來控制自身流程的,

  他會使此線程暫停執行一段時間,而把執行機會讓給其他線程,等到計時時間一到,此線程會自動甦醒

  wait()方法是object類的方法,用於線程間通信,這個方法會使當前擁有該對象鎖的進程等待,

  直到其他線程調用notify()方法或者notifyAll()時才醒來,不過開發人員也可以給他指定一個時間,自動醒來。

  wait()方法必須放在同步控制方法和同步代碼塊中使用

  sleep()方法則可以放在任何地方使用,但是必須捕獲異常

  13.synchronize與lock的區別

  共同點:

  都可以使線程安全(鎖)

  不同點:

  Lock是一個接口,而synchronized是關鍵字。

  synchronized會自動釋放鎖,而Lock必須手動釋放鎖。

  Lock可以讓等待鎖的線程響應中斷,而synchronized不會,線程會一直等待下去。

  通過Lock可以知道線程有沒有拿到鎖,而synchronized不能。

  Lock能提高多個線程讀操作的效率。

  synchronized能鎖住類、方法和代碼塊,而Lock是塊範圍內的


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章