1. 程式人生 > >java 併發中 volitile、synchronized和lock的比較(一)

java 併發中 volitile、synchronized和lock的比較(一)

1、volitile和(synchronnized、lock)

        首先比較volitile和synchronnized,volitile執行緒不安全,但是synchronized則是執行緒安全的。

        volitile修飾的變數主要作用讓變數的改變立即寫到主存,這樣在其它的執行緒檢視此變數的時候是最新的值。Java中為了加快程式的執行效率,對一些變數的操作通常是在該執行緒的暫存器或是CPU快取上進行的,之後才會同步到主存中,而加了volatile修飾符的變數則是直接讀寫主存

        當我們使用lock和synchronized的時候,也可以保證可見性,而且可以保證原子性。synchronized可以修飾一個程式碼塊或者一個方法等,但是顯然很多時候volitile的效能要優於synchronized的。

2、synchronized和lock的比較

          兩者的最直觀的感受就是一個是關鍵字、一個是類。

          關鍵字更貼近底層,不像類那麼好操作,所以呢一旦synchronized修飾的方法或者程式碼塊之類的拿到鎖以後,只有兩種情況會釋放鎖:

                一是修飾的方法或者程式碼塊執行完畢,二是執行出現異常,會釋放鎖。

                lock則是可以更加靈活應用,可以直接呼叫lock.lock,也可以呼叫lock.tryLock()等,獲取到鎖,那麼tryLock()方法更加在未能獲得鎖的情況下仍然就可以執行下面的不會一直等待,lock介面中還定義了一個方法,就是lockInterruptibly(),


                    1)如果當前執行緒未被中斷,則獲取鎖。

                    2)如果該鎖沒有被另一個執行緒保持,則獲取該鎖並立即返回,將鎖的保持計數設定為 1。

                    3)如果當前執行緒已經保持此鎖,則將保持計數加 1,並且該方法立即返回。

                    如果該鎖被另一個執行緒持有,則該執行緒不可被排程(disabled for thread scheduling purposes)(即阻塞狀態,CPU不會給該執行緒分配時間片)直到該執行緒獲取到該鎖,並且在獲取到鎖後,將保持計數設定為1

                    4)如果當前執行緒獲得該鎖,則將鎖保持計數設定為 1。

                    如果當前執行緒:

                    1)在進入此方法時已經設定了該執行緒的中斷狀態;或者

                    2)在等待獲取鎖的同時被中斷。

                    則丟擲 InterruptedException,並且清除當前執行緒的已中斷狀態。

                    5)在此實現中,因為此方法是一個顯式中斷點,所以要優先考慮響應中斷,而不是響應鎖的普通獲取或

                    重入獲取。

      未完待續