「非線程安全」問題存在於「實例變量」中,若是是方法內部的私有變量,則不存在線程安全問題。這是由於方法內部的變量都是私有形成的。java
synchronized 獲取的都是對象鎖。若是多個線程訪問多個對象,則JVM會建立多個鎖。安全
A線程持有object 對象的的Lock鎖,B線程能夠異步調用A線程非同步方法。A線程持有object 對象的的Lock鎖,B線程若是在這個時調用object對象中的synchronized類型的方法則須要等待。多線程
synchronized擁有鎖重入的功能。當一個線程獲得一個對象鎖後,再次請求對象鎖時是能夠再次獲得該對象的鎖。異步
可重入鎖支持在父子類繼承的環境中。工具
當一個線程出現異常,其持有的鎖自動釋放。this
同步不具備繼承。線程
synchronized(非this對象)同步代碼塊格式時,持有不一樣的對象監視器是異步的效果。對象
synchronized還能夠做用在static靜態方法上,那是對*.java文件對應的Class類進行加鎖。繼承
使用JDK自帶工具查看線程是否死鎖:進入JDK安裝目錄,bin目錄下,執行jps命令。再執行jstack -l xxx 。內存
volatile 是變量在多個線程可見。強制從公共堆棧中取得變量的值,而不是從線程私有數據棧中取得變量的值。
volatile不支持原子性。
volatile vs sysnchronized:
變量在內存中的過程:
執行完同步代碼就會釋放對象的鎖;在執行同步代碼的過程當中,遇到異常而致使線程終止,鎖也會被釋放;在執行同步代碼的過程當中,執行了鎖對象所屬的wait()方法,這個線程會釋放鎖對象,而此線程對象會進入線程等待池中等待喚醒。
join()的做用是等待線程對象銷燬。在內部使用wait()方法進行等待。
join(long) vs sleep:前者在指定時間後會釋放鎖,然後者不會。
ThreadLocal 解決的是變量在不一樣線程之間的隔離性。
InheritableThreadLocal 能夠在子線程中取得父線程繼承下來的值。
Lock.getHoldCount()方法能夠查詢當前線程保持此鎖定的個數,即調用lock方法的次數;getQueueLength()返回正等待獲取此鎖定的線程估計數;getWaitQueueLength(Condition condition)返回等待與此鎖定相關的給定條件condition的線程估計數。
其餘方法:
condition.awaitUntil(xxx):設置線程特定時間後自動喚醒。在等待中,能夠被其餘線程提早喚醒。
ReentrantReadWriteLock:多個線程可讀,一個線程寫。該鎖維護2個鎖,一個讀鎖,也稱爲共享鎖,一個寫入鎖,也稱爲拍他鎖。多個讀鎖之間不互斥,讀鎖寫鎖互斥,寫鎖與寫鎖互斥。