collection的子接口list和se html
list:①,容許重複對象②,能夠插入多個null元素③,有序容器java
④,經常使用的實現類有ArrayList、LinkedList和Vector,ArrayList使用索引隨意訪問,而LinkedList則更適合常常從list中添加刪除的場合。安全
set:①,不能有重複元素②,無序容器③,只能有一個null元素多線程
④,實現類有HashSet、LinkedHashSet、TreeSet框架
map:①,map不是collection的子接口或實現類,是一個接口②,map的每一個Entry都有兩個對象,一個鍵一個值,鍵不能重複。spa
③,能夠有多個null值,但只能有一個null鍵.net
④,實現類有HashMap、LinkedHashMap、HashTable、TreeMap線程
一、做者不一樣code
二、時間不一樣,Hashtable自java發佈以來,HashMap產生於jdk1.2htm
三、繼承的父類不一樣HashTable繼承Dictinary類,HashMap繼承AbstractMap類
四、Hashtable既不支持Null key也不支持Null value
五、HashMap中,null能夠做爲鍵,判斷是否存在一個鍵不能使用get()方法,當職位null時get()方法返回null,應該使用containsKey()方法判斷。
六、Hashtable線程安全,每一個方法都加入了Synchronize方法。當須要多線程操做的時候可使用線程安全的ConcurrentHashMap。ConcurrentHashMap雖然也是線程安全的,可是它的效率比Hashtable要高好多倍。由於ConcurrentHashMap使用了分段鎖,並不對整個數據進行鎖定。
七、爲了獲得元素的位置,首先須要根據元素的 KEY計算出一個hash值,而後再用這個hash值來計算獲得最終的位置。hash值的方法不一樣,Hashtable直接使用對象的hashCode,hashCode是JDK根據對象的地址或者字符串或者數字算出來的int類型的數值。而後再使用除留餘數發來得到最終的位置。
Hashtable在計算元素的位置時須要進行一次除法運算,而除法運算是比較耗時的。
HashMap爲了提升計算效率,將哈希表的大小固定爲了2的冪,這樣在取模預算時,不須要作除法,只須要作位運算。位運算比除法的效率要高不少。
HashMap的效率雖然提升了,可是hash衝突卻也增長了。由於它得出的hash值的低位相同的機率比較高,而計算位運算
爲了解決這個問題,HashMap從新根據hashcode計算hash值後,又對hash值作了一些運算來打散數據。使得取得的位置更加分散,從而減小了hash衝突。固然了,爲了高效,HashMap只作了一些簡單的位處理。從而不至於把使用2 的冪次方帶來的效率提高給抵消掉。
https://www.cnblogs.com/chengxiao/p/6059914.html
https://blog.csdn.net/helei810304/article/details/79786606
https://blog.csdn.net/m0_37840000/article/details/79756932
建立線程的四種方式:
①繼承Thread類,重寫run方法
② 實現Runnable接口,重寫run方法
③使用線程池例如用Executor框架
④使用Callable和Future建立線程
--------繼承Thread方式--------------------------------------------------------------
public class MyThread extends Thread{
public void run(){//重寫run方法}
} public class Test{ public static void main(String[] args){ new MyThread().start();//啓動線程 } }
-----實現Runnable接口方式-----------------------------------------------
public class MyThread implements Runnable{
public void run(){} } public class test{ public static void main(String[] args){ MyThrea tt = new MyThread(); Thread thread = new Thread(tt); thread.start(); } }
------------------------使用Callable和Future建立線程---------------------
1】建立Callable接口的實現類,並實現call()方法,而後建立該實現類的實例(從java8開始能夠直接使用Lambda表達式建立Callable對象)。
2】使用FutureTask類來包裝Callable對象,該FutureTask對象封裝了Callable對象的call()方法的返回值 3】使用FutureTask對象做爲Thread對象的target建立並啓動線程(由於FutureTask實現了Runnable接口) 4】調用FutureTask對象的get()方法來得到子線程執行結束後的返回值 代碼實例: public class Main { public static void main(String[] args){ MyThread3 th=new MyThread3(); //使用Lambda表達式建立Callable對象 //使用FutureTask類來包裝Callable對象 FutureTask<Integer> future=new FutureTask<Integer>( (Callable<Integer>)()->{ return 5; } ); new Thread(task,"有返回值的線程").start();//實質上仍是以Callable對象來建立並啓動線程 try{ System.out.println("子線程的返回值:"+future.get());//get()方法會阻塞,直到子線程執行結束才返回 }catch(Exception e){ ex.printStackTrace(); } } }
1、sleep()
使當前線程(即調用該方法的線程)暫停執行一段時間,讓其餘線程有機會繼續執行,但它並不釋放對象鎖。也就是說若是有synchronized同步快,其餘線程仍然不能訪問共享數據。注意該方法要捕捉異常。
例若有兩個線程同時執行(沒有synchronized)一個線程優先級爲MAX_PRIORITY,另外一個爲MIN_PRIORITY,若是沒有Sleep()方法,只有高優先級的線程執行完畢後,低優先級的線程纔可以執行;可是高優先級的線程sleep(500)後,低優先級就有機會執行了。 總之,sleep()可使低優先級的線程獲得執行的機會,固然也可讓同優先級、高優先級的線程有執行的機會。 2、join() join()方法使調用該方法的線程在此以前執行完畢,也就是等待該方法的線程執行完畢後再往下繼續執行。注意該方法也須要捕捉異常。 3、yield() 該方法與sleep()相似,只是不能由用戶指定暫停多長時間,而且yield()方法只能讓同優先級的線程有執行的機會。
四、wait:Object類的方法,必須放在循環體和同步代碼塊中,執行該方法的線程會釋放鎖,進入線程等待池中等待被再次喚醒(notify隨機喚醒,notifyAll所有喚醒,線程結束自動喚醒)即放入鎖池中競爭同步鎖
(1)生命週期的五種狀態
新建(new Thread) 當建立Thread類的一個實例(對象)時,此線程進入新建狀態(未被啓動)。 例如:Thread t1=new Thread(); 就緒(runnable) 線程已經被啓動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候獲得CPU資源。例如:t1.start(); 運行(running) 線程得到CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優先級更高的線程進入,線程將一直運行到結束。 死亡(dead) 當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。 天然終止:正常運行run()方法後終止 異常終止:調用stop()方法讓一個線程終止運行 堵塞(blocked) 因爲某種緣由致使正在運行的線程讓出CPU並暫停本身的執行,即進入堵塞狀態。 正在睡眠:用sleep(long t) 方法可以使線程進入睡眠方式。一個睡眠着的線程在指定的時間過去可進入就緒狀態。 正在等待:調用wait()方法。(調用motify()方法回到就緒狀態) 被另外一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)