真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

volatile和synchronize有哪些區(qū)別-創(chuàng)新互聯(lián)

小編給大家分享一下volatile和synchronize有哪些區(qū)別,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

成都創(chuàng)新互聯(lián)公司自2013年起,先為桓仁等服務(wù)建站,桓仁等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為桓仁企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

區(qū)別:1、volatile不會(huì)造成線程的阻塞;synchronized可能會(huì)造成線程的阻塞。2、volatile保證數(shù)據(jù)的可見(jiàn)性,但不能保證原子性;而synchronized可以保證原子性,也可以間接保證可見(jiàn)性。

可見(jiàn)性(visibility)

可見(jiàn)性:一個(gè)線程對(duì)共享變量做了修改之后,其他的線程立即能夠看到(感知到)該變量這種修改(變化)。
Java內(nèi)存模型是通過(guò)將在工作內(nèi)存中的變量修改后的值同步到主內(nèi)存,在讀取變量前從主內(nèi)存刷新新值到工作內(nèi)存中,這種依賴主內(nèi)存的方式來(lái)實(shí)現(xiàn)可見(jiàn)性的。

原子性(atomicity)

原子性:一個(gè)操作不能被打斷,要么全部執(zhí)行完畢,要么不執(zhí)行。
java內(nèi)存模型所保證的是,同線程內(nèi),所有的操作都是由上到下的,但是多個(gè)線程并行的情況下,則不能保證其操作的有序性。

有序性

有序性:在本線程內(nèi)觀察,操作都是有序的;如果在一個(gè)線程中觀察另外一個(gè)線程,所有的操作都是無(wú)序的。

java內(nèi)存模型所保證的是,同線程內(nèi),所有的操作都是由上到下的,但是多個(gè)線程并行的情況下,則不能保證其操作的有序性。
計(jì)算機(jī)在執(zhí)行程序時(shí),為了提高性能,編譯器個(gè)處理器常常會(huì)對(duì)指令做重排,一般分為以下 3 種
volatile和synchronize有哪些區(qū)別
單線程環(huán)境里面確保程序最終執(zhí)行的結(jié)果和代碼執(zhí)行的結(jié)果一致
處理器在進(jìn)行重排序時(shí)必須考慮指令之間的數(shù)據(jù)依賴性
多線程環(huán)境中線程交替執(zhí)行,由于編譯器優(yōu)化重排的存在,兩個(gè)線程中使用的變量能否保證用的變量能否一致性是無(wú)法確定的,結(jié)果無(wú)法預(yù)測(cè)
考試先做會(huì)做的,不會(huì)做的后做。

public void mySort(){
int x = 11; //1
int y = 12; //2
x= x+5; // 3
y = x*x;//4

可能的順序1234 2134 1324,不可能的屬性4在1 和3前,因?yàn)橛袛?shù)據(jù)依賴性。

volatile和synchronize有哪些區(qū)別
volatile禁止指令重排。

public class ReSortSeqDemo {
    int a = 0;
    boolean flag = false;
    
    public void method01() {
        a = 1;           // flag = true;
                         // ----線程切換----
        flag = true;     // a = 1;
    }

    public void method02() {
        if (flag) {
            a = a + 3;
            System.out.println("a = " + a);
        }
    }

}

如果兩個(gè)線程同時(shí)執(zhí)行,method01 和 method02 如果線程 1 執(zhí)行 method01 重排序了,然后切換的線程 2 執(zhí)行 method02 就會(huì)出現(xiàn)不一樣的結(jié)果。

禁止指令排序

volatile 實(shí)現(xiàn)禁止指令重排序的優(yōu)化,從而避免了多線程環(huán)境下程序出現(xiàn)亂序的現(xiàn)象

先了解一個(gè)概念,內(nèi)存屏障(Memory Barrier)又稱內(nèi)存柵欄,是一個(gè) CPU 指令,他的作用有兩個(gè):

保證特定操作的執(zhí)行順序
保證某些變量的內(nèi)存可見(jiàn)性(利用該特性實(shí)現(xiàn) volatile 的內(nèi)存可見(jiàn)性)
由于編譯器個(gè)處理器都能執(zhí)行指令重排序優(yōu)化,如果在指令間插入一條 Memory Barrier 則會(huì)告訴編譯器和 CPU,不管什么指令都不能個(gè)這條 Memory Barrier 指令重排序,也就是說(shuō)通過(guò)插入內(nèi)存屏障禁止在內(nèi)存屏障前后執(zhí)行重排序優(yōu)化。內(nèi)存屏障另一個(gè)作用是強(qiáng)制刷出各種 CPU 緩存數(shù)據(jù),因此任何 CPU 上的線程都能讀取到這些數(shù)據(jù)的新版本。

下面是保守策略下,volatile寫插入內(nèi)存屏障后生成的指令序列示意圖:
volatile和synchronize有哪些區(qū)別
下面是在保守策略下,volatile讀插入內(nèi)存屏障后生成的指令序列示意圖:
volatile和synchronize有哪些區(qū)別

線程安全性保證

工作內(nèi)存與主內(nèi)存同步延遲現(xiàn)象導(dǎo)致可見(jiàn)性問(wèn)題
可以使用 synchronzied 或 volatile 關(guān)鍵字解決,它們可以使用一個(gè)線程修改后的變量立即對(duì)其他線程可見(jiàn)
對(duì)于指令重排導(dǎo)致可見(jiàn)性問(wèn)題和有序性問(wèn)題
可以利用 volatile 關(guān)鍵字解決,因?yàn)?volatile 的另一個(gè)作用就是禁止指令重排序優(yōu)化

volatile

它所修飾的變量不保留拷貝,直接訪問(wèn)主內(nèi)存中的。

在Java內(nèi)存模型中,有main memory,每個(gè)線程也有自己的memory (例如寄存器)。為了性能,一個(gè)線程會(huì)在自己的memory中保持要訪問(wèn)的變量的副本。這樣就會(huì)出現(xiàn)同一個(gè)變量在某個(gè)瞬間,在一個(gè)線程的memory中的值可能與另外一個(gè)線程memory中的值,或者main memory中的值不一致的情況。 一個(gè)變量聲明為volatile,就意味著這個(gè)變量是隨時(shí)會(huì)被其他線程修改的,因此不能將它c(diǎn)ache在線程memory中。

使用場(chǎng)景

您只能在有限的一些情形下使用 volatile 變量替代鎖。要使 volatile 變量提供理想的線程安全,必須同時(shí)滿足下面兩個(gè)條件:
1)對(duì)變量的寫操作不依賴于當(dāng)前值。
2)該變量沒(méi)有包含在具有其他變量的不變式中。

volatile最適用一個(gè)線程寫,多個(gè)線程讀的場(chǎng)合。
如果有多個(gè)線程并發(fā)寫操作,仍然需要使用鎖或者線程安全的容器或者原子變量來(lái)代替。

synchronized

當(dāng)它用來(lái)修飾一個(gè)方法或者一個(gè)代碼塊的時(shí)候,能夠保證在同一時(shí)刻最多只有一個(gè)線程執(zhí)行該段代碼。

  1. 當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象object中的這個(gè)synchronized(this)同步代碼塊時(shí),一個(gè)時(shí)間內(nèi)只能有一個(gè)線程得到執(zhí)行。另一個(gè)線程必須等待當(dāng)前線程執(zhí)行完這個(gè)代碼塊以后才能執(zhí)行該代碼塊。
  2. 然而,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),另一個(gè)線程仍然可以訪問(wèn)該object中的非synchronized(this)同步代碼塊。
  3. 尤其關(guān)鍵的是,當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),其他線程對(duì)object中所有其它synchronized(this)同步代碼塊的訪問(wèn)將被阻塞。
  4. 當(dāng)一個(gè)線程訪問(wèn)object的一個(gè)synchronized(this)同步代碼塊時(shí),它就獲得了這個(gè)object的對(duì)象鎖。結(jié)果,其它線程對(duì)該object對(duì)象所有同步代碼部分的訪問(wèn)都被暫時(shí)阻塞。
    volatile和synchronize有哪些區(qū)別
    共享資源及增刪改的對(duì)象。

Lock

從jdk 5.0開(kāi)始,java提供了更強(qiáng)大的線程同步機(jī)制-通過(guò)顯示定義同步鎖對(duì)象來(lái)實(shí)現(xiàn)同步,同步鎖使用Lock對(duì)象充當(dāng)。

java.util.concurrent.Locks.Lock接口是控制多個(gè)線程對(duì)共享資源進(jìn)行訪問(wèn)的工具。鎖提供了對(duì)共享資源的獨(dú)占訪問(wèn),每次只能有一個(gè)線程對(duì)Lock對(duì)象加鎖,線程開(kāi)始訪問(wèn)共享資源之前應(yīng)先獲得Lock對(duì)象。

ReentrantLock類實(shí)現(xiàn)了Lock,它擁有與synchronized相同的并發(fā)性和內(nèi)存語(yǔ)義,在實(shí)現(xiàn)線程安全的控制中,比較常用的是ReentrantLock,可以顯示加鎖、釋放鎖。

volatile和synchronize有哪些區(qū)別

區(qū)別

volatile和synchronized

  • volatile是變量修飾符,而synchronized則作用于一段代碼或方法。

  • volatile只是在線程內(nèi)存和“主”內(nèi)存間同步某個(gè)變量的值;而synchronized通過(guò)鎖定和解鎖某個(gè)監(jiān)視器同步所有變量的值, 顯然synchronized要比volatile消耗更多資源。

  • volatile不會(huì)造成線程的阻塞;synchronized可能會(huì)造成線程的阻塞。

  • volatile保證數(shù)據(jù)的可見(jiàn)性,但不能保證原子性;而synchronized可以保證原子性,也可以間接保證可見(jiàn)性,因?yàn)樗鼤?huì)將私有內(nèi)存中和公共內(nèi)存中的數(shù)據(jù)做同步。

  • volatile標(biāo)記的變量不會(huì)被編譯器優(yōu)化;synchronized標(biāo)記的變量可以被編譯器優(yōu)化。

線程安全包含原子性和可見(jiàn)性兩個(gè)方面,Java的同步機(jī)制都是圍繞這兩個(gè)方面來(lái)確保線程安全的。
關(guān)鍵字volatile主要使用的場(chǎng)合是在多個(gè)線程中可以感知實(shí)例變量被修改,并且可以獲得新的值使用,也就是多線程讀取共享變量時(shí)可以獲得新值使用。

關(guān)鍵字volatile提示線程每次從共享內(nèi)存中讀取變量,而不是私有內(nèi)存中讀取,這樣就保證了同步數(shù)據(jù)的可見(jiàn)性。但是要注意的是:如果修改實(shí)例變量中的數(shù)據(jù)

例如:i++,也就是i=i+1,則這樣的操作其實(shí)并不是一個(gè)原子操作,也就是非線程安全的。表達(dá)式i++操作步驟分解如下:
1)從內(nèi)存中取出i的值。
2)計(jì)算i的值;
3)將i的值寫到內(nèi)存中。
假如在第2步計(jì)算值得時(shí)候,另外一個(gè)線程也修改i的值,name這個(gè)時(shí)候就會(huì)出現(xiàn)臟讀數(shù)據(jù)。解決的辦法就是使用synchronized關(guān)鍵字。 所以說(shuō)volatile本身并不處理數(shù)據(jù)的原子性,而是強(qiáng)制對(duì)數(shù)據(jù)的讀寫及時(shí)的影響到主內(nèi)存中。

synchronized 和Lock

Lock是顯示鎖(手動(dòng)開(kāi)啟和關(guān)閉,別忘記關(guān)閉鎖),synchronized是隱式鎖,出了作用域自動(dòng)釋放鎖。
Lock只有代碼塊鎖,synchronized可以作用代碼塊和方法。
使用Lock鎖,jvm花費(fèi)較少的時(shí)間來(lái)調(diào)度線程,性能更好。并且具有更好的擴(kuò)展性(提供更多的子類)。
使用順序:Lock->同步代碼塊(已經(jīng)進(jìn)入了方法體,分配了相應(yīng)資源)->同步方法(在方法體之外)。

以上是volatile和synchronize有哪些區(qū)別的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


網(wǎng)頁(yè)題目:volatile和synchronize有哪些區(qū)別-創(chuàng)新互聯(lián)
本文鏈接:http://weahome.cn/article/hjojs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部