多線程數據庫
第一章編程
一。終止線程的三種方法:設計模式
1.使用退出標誌,是縣城正常退出,也就是當run方法完成後線程終止。數組
2.stop不推薦緩存
3.使用interrupt(打了一箇中止標記,並非真的中止線程)。安全
1)interrupt+throw new interruptexception(推薦使用,catch塊中還能夠將異常向上拋,使線程中止的事件得以傳播。)多線程
2) interrupt+return併發
二。this.interrupted()和this.isInterrupted()框架
1)this.interrupted():測試當前線程是否已是中斷狀態,執行後具備將狀態標誌清除爲false的功能。異步
2)測試線程Thread對象是否已是中斷狀態,但不清除狀態標誌。
三。stop方法爲何不用?
1)已經做廢,由於若是強制讓線程中止則有可能使一些清理性的工做得不到完成。
2)另一個狀況就是對鎖定的對象鏡像了「解鎖」,致使數據得不到同步的處理,出現數據不一致的問題。
四。suspend與resume的缺點:
1)獨佔鎖
2)不一樣步
五。守護進程:保姆,提供便利服務,只要當前進程實例中存在任何一個非守護進程 沒有結束,守護進程就在工做,只有當最後一個非守護進程結束時,守護進程才隨着jvm一同結束工做。典型應用是GC
第二章
一。synchronized鎖重入:
本身能夠再次獲取本身的內部鎖,好比有一條線程得到了某個對象的鎖,此時這個對象鎖尚未釋放,當其再次想要獲取這個對象的鎖的時候仍是能夠得到的,若是不可鎖重入的話,就會形成死鎖。
二。出現異常,鎖自動釋放。
三。同步不具備繼承性
四。在使用同步synchronized(this)代碼塊時須要注意的是,當一個線程訪問object的一個synchronized同步代碼塊時,其餘線程對同一個object中全部其餘synchronized同步代碼塊的訪問將被阻塞,這說明synchronized使用的「對象監視器」是一個。
五。能夠將this做爲對象監視器,也能夠將任意對象做爲對象監視器。
六。synchroniezd(this)和synchronized同步方法的對象監視器都是對象自己。
七。鎖非this對象具備必定的優勢:若是在一個類中有不少的synchronized方法,這時雖然能實現同步,但會受到阻塞,因此會影響運行效率;但若是使用同步代碼塊鎖非this對象,則synchronized(非this)代碼塊中的程序與同步方法是異步的,不與其餘鎖this同步方法爭搶this鎖,則能夠大大提升效率。
八。synchronized還能夠用在static靜態方法上,對類進行加鎖。和對象鎖是不同的鎖。
九。同步synchronized(class)代碼塊的做用其實和synchronized static方法的做用同樣。
十。因爲JVM中Strring常量池緩存的緣由,在大多數的狀況下,同步synchronized帶麥克都不使用String做爲鎖對象,而改用其餘,好比new Obj,但它不放入緩存池中。或者byte[] a=new byte[0];說明:零長度的byte數組對象建立起來將比任何對象都經濟――查看編譯後的字節碼:生成零長度的byte[]對象只需3條操做碼,而Object lock = new Object()則須要7行操做碼。
十一,只要對象不變,即便對象的屬性被改變,運行的結果仍是同步。
十二。volatile:強制從公共堆棧中取得變量值,而不是從線程私有數據棧彙總取得變量的值。不支持原子性。
第三章 線程通訊。
一。wait使線程中止運行,而notify使中止的線程繼續運行。在調用wait以前,線程必須得到該對象的對象級別鎖,即只能在同步方法或同步塊中調用wait方法。在執行wait後,當前線程釋放鎖。若是調用wait時沒有持有適當的鎖,則拋出illegalMonitorStateException。notify調用沒有持有適當的鎖也會illegalMonitorStateException。
二。notify方法執行後並不當即釋放鎖,wait當即釋放。若是發出notify操做時沒有處於阻塞狀態中的線程,那麼該命令會被忽略。
三。 線程切換:
1)新建立一個新的線程對象後,再調用它的star()方法,系統會爲此線程分配CPU資源,使其處於Runnable (可運行)狀態,這是一個準備運行的階段。若是線程搶佔到CPU資源,此線程就處於Running(運行)狀態。
2) Runnable狀態和Running狀態可相互切換,由於有可能線程運行一段時間後, 有其餘高優先級的線程搶佔了CPU資源,這時此線程就從Running狀態變成Runnable狀態。
線程進入Runnable狀態大致分爲以下5種狀況:
口調用sleep)方法後通過的時間超過了指定的休眠時間。
口線程調用的阻塞IO已經返回,阻塞方法執行完畢。
口線程成功地得到了試圖同步的監視器。
口線程正在等待某個通知,其餘線程發出了通知。
口處於掛起狀態的線程調用了resume恢復方法。
3) Blocked是阻塞的意思,例如遇到了一個IO操做,此時CPU處於空閒狀態,可能會轉而把CPU時間片分配給其餘線程,這時也能夠稱爲「暫停」狀態。Blocked 狀態結束後,
進人Runnable狀態,等待系統從新分配資源。
出現阻塞的狀況大致分爲以下5種:
口線程調用seep方法,主動放棄佔用的處理器資源。
口線程調用了阻塞式IO方法,在該方法返回前,該線程被阻塞。
口線程試圖得到一個同步監視器,但該同步監視器正被其餘線程所持有。
口線程等待某個通知。
口程序調用了suspend 方法將該線程掛起。此方法容易致使死鎖,儘可能避免使用該方法。
4) run(方法運行結束後進人銷燬階段,整個線程執行完畢。
四。
1.sleep方法不釋放鎖。notify必須執行完notify方法所在的同步synchronized代碼塊後才釋放鎖。
2.
1)執行完同步代碼塊就會釋放對象的鎖。
2)在執行同步代碼塊的過程當中,遇到異常而致使線程終止,鎖也會被釋放。
3)在執行同步代碼塊的過程當中,執行了鎖所屬對象的wait方法,這個過程會釋放對象鎖,而此線程對象會進入線程等待池中,等待被喚醒。
五。線程之間通訊方式之:管道 pipeStream 4個類:PipeInputStream PipedReader
六。方法join:等待線程對象銷燬,具備使線程排隊運行的做用。有些相似同步的運行效果。join與synchronized的區別:join內部使用wait進行等待,而synchronize使用的是對象監視器原理同步。
七。join(long)和wait(long)的區別:方法join(long)功能內部是使用wait(long)來實現的,因此join方法具備釋放鎖的特色。
八。threadLocal類:主要解決的問題是每一個線程綁定本身的值。每個線程有本身的私有數據。
InheritableThreadLocal能夠在子進程中取得父進程繼承下來的值。
第四章 Lock
一。lock.lock待的線程持有了「對象監視器」,其餘線程只有等待被釋放時再次爭搶。
二。藉助condition對象能夠實現多路通知的功能,也就是在一個lock對象裏面能夠建立多個condition(對象監視器)實例,線程對象能夠註冊在指定的condition中,從而有選擇的進行線程通知,在調度上更靈活。在使用notify/notifyall方法進行通知時,被通知的線程時jvm隨機選擇的。但使用rerntrantlock結合Condition類是能夠實現「選擇性通知」。synchronized至關於整個lock對象只有一個單一的condition對象,全部的線程都註冊在它一個對象上。
三。wait至關於condition的await。wait(long timeout)至關於await(long)。notify至關於condition的signal,notifyall至關於signalAll。
四。想要實現一對一通知,只需建立對於的condition便可。Lock lock=new ReentrantLock;Condiition condition=lock.newCondition;
五。公平鎖和非公平鎖,是否按照線程加鎖的順序。FIFO.建立鎖的時候能夠用構造方法傳入。默認是非公平鎖。
六。使用condition能夠實現線程的按順序執行。使用多個condition和一個變量,這個變量要一直改變使一個線程能夠執行,其餘線程等待。
七。讀寫鎖ReentrantReadWriteLock,提升代碼運行速度(在不須要操做實例變量的方法中)。讀操做相關的鎖,也稱共享索女,寫操做的鎖,也稱排它鎖。也就是讀讀不互斥,讀寫互斥。寫寫互斥。即多個線程能夠同時讀取操做,可是同一時刻只容許一個Thread寫入操做。
第六七章 單例模式與多線程
一。使用DCL 雙檢查鎖機制來實現多線程環境中的延遲加載單例設計模式。
那麼咱們爲何要使用兩個if判斷這個對象當前是否是空的呢 ?由於當有多個線程同時要建立對象的時候,多個線程有可能都中止在第一個if判斷的地方,等待鎖的釋放,而後多個線程就都建立了對象,這樣就不是單例模式了,因此咱們要用兩個if來進行這個對象是否存在的判斷。
其餘方式:使用靜態內置類。使用靜態代碼塊。使用枚舉類:構造方法自動調用。
二。simpledateformat非線程安全。解決方法一:建立多個simpleDateFormat。二:threadLocal
Java併發編程的藝術:
一。synchronized和lock的區別和優點
缺乏了隱式獲取釋放鎖的便捷性,可是卻擁有了鎖獲取與釋放的可操做性、可中斷的獲取鎖以及超時獲取鎖等synchronized不具有的同步特性。
1)嘗試非阻塞地獲取鎖
2)能被中斷地獲取鎖
3)超時獲取鎖
二。abstractQueueSynchronizer隊列同步器,是用來構建鎖或其餘同步組件的基礎框架。(不一樣類型的同步組件ReentrantLock、ReentrantReadWriteLock和CountDownLatch等)
三。concurrentHashMap:HashTable在競爭激烈的併發環境下表現出效率低下的緣由是全部訪問HashTable的線程都必須競爭通一把鎖,假若有多把鎖,每一把鎖用於鎖容器其中一部分數據,那麼當多線程訪問容器裏不一樣數據段的數據時,線程間就不會存在鎖競爭,從而能夠有效提升併發訪問下來,這就是concurrentHashMap的鎖分段技術。首先將數據分紅一段一段存儲,而後每一段數據配一把鎖當一個線程佔用鎖訪問期中一個段數據時,其餘段的數據也能被其餘線程訪問。
四。CountDownLatch()和CyclicBarrier
cyclicBarrier:讓一組線程到達一個屏障時被阻塞,知道最後一個線程到達屏障時,屏障纔會開門,全部被屏障鏈接的線程纔會繼續進行。
countDownLatch的計數器只能使用一次,而cyclicBarrier的計數器可使用reset方法重置。
CountDownLatch:主要是-1操做,能夠用在一個線程的n個步驟,也能夠是n個線程。
semaphone:能夠用來作流量控制,特別是公共資源有限的場景。好比數據庫鏈接。acquire獲取、release歸還。
線程間交換數據的Exchanger:用於線程間協做。線程間數據交換,它提供一個同步點,在這個同步點,兩個線程能夠交換彼此的數據。若是一個線程先執行exchanger方法,它會一直等待第二個線程也執行,當兩個線程到達同步點時,這兩個線程就能夠交換數據,將本線程生產出來的數據傳遞給對方。