1、繼承Thread類,重寫run()方法,new一個執行個體對象,調用start()方法;
2、實作Runnable接口,重寫run()方法,new一個執行個體對象,作為Thread的target來建立;
3、實作Callable接口
初生、就緒、運作、阻塞、消亡
重載是對類中同名方法采取的操作,通過改變形參數量、類型、順序,使得同一方法可以有不同的傳參形式
重寫是子類對父類中同名方法的替換,傳回值,方法名,參數類型必須一緻,可以實作多态。
重寫遵循"兩同兩小一大"
方法名、形參相同
傳回值、抛出異常更小
權限修飾符更大
封裝:限制使用者對類的通路,隻暴露必要的接口給使用者,可以減少使用者的誤操作,友善開發者對内部細節的調整和疊代
繼承:實作對類的拓展,減少重複代碼。私有屬性和方法子類無法通路
多态:實作接口或重寫父類方法,程式運作時才決定實際調用的方法
String底層是用final修飾的數組,視為常量,不可變
StringBuffer底層的方法用sychonized鎖,線程安全
StringBuild線程不安全
抽象類更像模闆,可以有非抽象方法
接口更像行為規範,隻能有抽象方法和static final變量
基本資料類型比較值,引用資料類型比較記憶體位址
equals未重寫,與==相同,重寫後一般比較對象内的值
重寫equals必須重寫hashcode 否則類的兩個執行個體對象一定不會相等
隻能修飾變量,不能修飾類和方法,阻止變量序列化
arrayList線程不安全,效率高
Vector線程安全,效率低
HashMap線程不安全效率高
HashTable線程安全效率低
HashMap支援nullkey nullvalue HashTable會報異常
HashMap的大小為2的幂次方,每次擴容翻倍,底層是數組+連結清單+紅黑樹,連結清單長度大于8時,如果數組長度大于64,連結清單會轉換成紅黑樹,否則進行數組擴容
計算HashCode,不同直接加入,相同進行equals比較
JDK1.7 使用segment,分段鎖,操作資料先擷取對應的segment鎖,效率比HashTable全表鎖高
JDK1.8 資料結構和HashMap一緻,改為synchronized,隻鎖連結清單或紅黑樹的首節點,效率進一步提高
線程是輕量級程序,線程共享統一程序的堆和方法區,每個線程有自己的程式計數器、本地方法棧、虛拟機棧
調用start方法線程進入就緒狀态,等待cpu配置設定時間片,是真正的多線程
調用run方法會直接執行該方法,還是在目前線程
第一次判斷null是為了快速傳回單例對象,就像先比較hash在進行equals
第二次判斷null + synchronized 是為了確定單例
volatile保證了有序性,防止指令重排
因為 singleton = new Singleton() 這句話可以分為三步:
1. 為 singleton 配置設定記憶體空間;
2. 初始化 singleton;
3. 将 singleton 指向配置設定的記憶體空間。
但是由于JVM具有指令重排的特性,執行順序有可能變成 1-3-2。 指令重排在單線程下不會出現問題,但是在多線程下會導緻一個線程獲得一個未初始化的執行個體。例如:線程T1執行了1和3,此時T2調用 getInstance() 後發現 singleton 不為空,是以傳回 singleton, 但是此時的 singleton 還沒有被初始化。
使用 volatile 會禁止JVM指令重排,進而保證在多線程下也能正常執行。
線程的建立和銷毀都需要消耗資源,比如記憶體空間,時間等
線程池可以重複利用已建立的線程,減少資源消耗
線程不需要建立,拿來即用,提高響應速度
線程池管理線程,保證線程不濫用,避免線程建立過多
Runnable不傳回結果和抛出異常,更加簡潔