成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Java并發(fā)編程-原子操作

SillyMonkey / 1977人閱讀

摘要:這個(gè)規(guī)則比較好理解,無(wú)論是在單線(xiàn)程環(huán)境還是多線(xiàn)程環(huán)境,一個(gè)鎖處于被鎖定狀態(tài),那么必須先執(zhí)行操作后面才能進(jìn)行操作。線(xiàn)程啟動(dòng)規(guī)則獨(dú)享的方法先行于此線(xiàn)程的每一個(gè)動(dòng)作。

1. 指令重排序

關(guān)于指令重排序的概念,比較復(fù)雜,不好理解。我們從一個(gè)例子分析:

public class SimpleHappenBefore {

    /** 這是一個(gè)驗(yàn)證結(jié)果的變量 */
    private static int a=0;

    /** 這是一個(gè)標(biāo)志位 */
    private static boolean flag=false;

    public static void main(String[] args) throws InterruptedException {

        //由于多線(xiàn)程情況下未必會(huì)試出重排序的結(jié)論,所以多試一些次
        for(int i = 0; i < 1000; i++){

            ThreadA threadA=new ThreadA();
            ThreadB threadB=new ThreadB();

            threadA.start();
            threadB.start();

            //這里等待線(xiàn)程結(jié)束后,重置共享變量,以使驗(yàn)證結(jié)果的工作變得簡(jiǎn)單些.
            threadA.join();
            threadB.join();

            a = 0;
            flag = false;
        }
    }

    static class ThreadA extends Thread{
        public void run(){
            a = 1;
            flag = true;
        }
    }

    static class ThreadB extends Thread{
        public void run(){
            if(flag){
                a = a * 1;
            }

            if(a == 0){
                System.out.println("ha,a==0");
            }
        }
    }
}

一個(gè)簡(jiǎn)單的展示Happen-Before的例子.
這里有兩個(gè)共享變量:a和flag,初始值分別為0和false.在ThreadA中先給a=1,然后flag=true.

如果按照有序的話(huà),那么在ThreadB中如果if(flag)成功的話(huà),則應(yīng)該a=1,而a=a*1之后a仍然為1,下方的if(a==0)應(yīng)該永遠(yuǎn)不會(huì)為真,永遠(yuǎn)不會(huì)打印.

但實(shí)際情況是:在試驗(yàn)100次的情況下會(huì)出現(xiàn)0次或幾次的打印結(jié)果,而試驗(yàn)1000次結(jié)果更明顯,有十幾次打印.

1.1. 什么是指令重排序

在虛擬機(jī)層面,為了盡可能減少內(nèi)存操作速度遠(yuǎn)慢于CPU運(yùn)行速度所帶來(lái)的CPU空置的影響,虛擬機(jī)會(huì)按照自己的一些規(guī)則(這規(guī)則后面再敘述)將程序編寫(xiě)順序打亂——即寫(xiě)在后面的代碼在時(shí)間順序上可能會(huì)先執(zhí)行,而寫(xiě)在前面的代碼會(huì)后執(zhí)行——以盡可能充分地利用CPU。

拿上面的例子來(lái)說(shuō):假如不是a=1的操作,而是a=new byte[1024*1024](分配1M空間),那么它會(huì)運(yùn)行地很慢,此時(shí)CPU是等待其執(zhí)行結(jié)束呢,還是先執(zhí)行下面那句flag=true呢?顯然,先執(zhí)行flag=true可以提前使用CPU,加快整體效率,當(dāng)然這樣的前提是不會(huì)產(chǎn)生錯(cuò)誤(什么樣的錯(cuò)誤后面再說(shuō))。雖然這里有兩種情況:后面的代碼先于前面的代碼開(kāi)始執(zhí)行;前面的代碼先開(kāi)始執(zhí)行,但當(dāng)效率較慢的時(shí)候,后面的代碼開(kāi)始執(zhí)行并先于前面的代碼執(zhí)行結(jié)束。不管誰(shuí)先開(kāi)始,總之后面的代碼在一些情況下存在先結(jié)束的可能。

不管怎么重排序,單線(xiàn)程程序的執(zhí)行結(jié)果不能被改變。編譯器、運(yùn)行時(shí)和處理器都必須遵守“as-if-serial”語(yǔ)義。拿個(gè)簡(jiǎn)單例子來(lái)說(shuō),

public void execute(){
    int a = 0;
    int b = 1;
    int c = a+b;
}

這里a=0,b=1兩句可以隨便排序,不影響程序邏輯結(jié)果,但c=a+b這句必須在前兩句的后面執(zhí)行。

2. happen-before

在JMM中,如果一個(gè)操作執(zhí)行的結(jié)果需要對(duì)另一個(gè)操作可見(jiàn),那么這兩個(gè)操作之間必須存在happens-before關(guān)系。

happens-before原則非常重要,它是判斷數(shù)據(jù)是否存在競(jìng)爭(zhēng)、線(xiàn)程是否安全的主要依據(jù),依靠這個(gè)原則,我們解決在并發(fā)環(huán)境下兩操作之間是否可能存在沖突的所有問(wèn)題。
happens-before原則定義如下:

如果一個(gè)操作happens-before另一個(gè)操作,那么第一個(gè)操作的執(zhí)行結(jié)果將對(duì)第二個(gè)操作可見(jiàn),而且第一個(gè)操作的執(zhí)行順序排在第二個(gè)操作之前。

兩個(gè)操作之間存在happens-before關(guān)系,并不意味著一定要按照happens-before原則制定的順序來(lái)執(zhí)行。如果重排序之后的執(zhí)行結(jié)果與按照happens-before關(guān)系來(lái)執(zhí)行的結(jié)果一致,那么這種重排序并不非法。

重排序在多線(xiàn)程環(huán)境下出現(xiàn)的概率還是挺高的,在關(guān)鍵字上有volatile和synchronized可以禁用重排序,除此之外還有一些規(guī)則,也正是這些規(guī)則,使得我們?cè)谄綍r(shí)的編程工作中沒(méi)有感受到重排序的壞處。

程序次序規(guī)則(Program Order Rule):在一個(gè)線(xiàn)程內(nèi),按照代碼順序,書(shū)寫(xiě)在前面的操作先行發(fā)生于書(shū)寫(xiě)在后面的操作。準(zhǔn)確地說(shuō)應(yīng)該是控制流順序而不是代碼順序,因?yàn)橐紤]分支、循環(huán)等結(jié)構(gòu)。
一段代碼在單線(xiàn)程中執(zhí)行的結(jié)果是有序的。注意是執(zhí)行結(jié)果,因?yàn)樘摂M機(jī)、處理器會(huì)對(duì)指令進(jìn)行重排序(重排序后面會(huì)詳細(xì)介紹)。雖然重排序了,但是并不會(huì)影響程序的執(zhí)行結(jié)果,所以程序最終執(zhí)行的結(jié)果與順序執(zhí)行的結(jié)果是一致的。故而這個(gè)規(guī)則只對(duì)單線(xiàn)程有效,在多線(xiàn)程環(huán)境下無(wú)法保證正確性。

監(jiān)視器鎖定規(guī)則(Monitor Lock Rule):一個(gè)unlock操作先行發(fā)生于后面對(duì)同一個(gè)對(duì)象鎖的lock操作。這里強(qiáng)調(diào)的是同一個(gè)鎖,而“后面”指的是時(shí)間上的先后順序,如發(fā)生在其他線(xiàn)程中的lock操作。
這個(gè)規(guī)則比較好理解,無(wú)論是在單線(xiàn)程環(huán)境還是多線(xiàn)程環(huán)境,一個(gè)鎖處于被鎖定狀態(tài),那么必須先執(zhí)行unlock操作后面才能進(jìn)行l(wèi)ock操作。

volatile變量規(guī)則(Volatile Variable Rule):對(duì)一個(gè)volatile變量的寫(xiě)操作發(fā)生于后面對(duì)這個(gè)變量的讀操作,這里的“后面”也指的是時(shí)間上的先后順序。
這是一條比較重要的規(guī)則,它標(biāo)志著volatile保證了線(xiàn)程可見(jiàn)性。通俗點(diǎn)講就是如果一個(gè)線(xiàn)程先去寫(xiě)一個(gè)volatile變量,然后一個(gè)線(xiàn)程去讀這個(gè)變量,那么這個(gè)寫(xiě)操作一定是happens-before讀操作的。

線(xiàn)程啟動(dòng)規(guī)則(Thread Start Rule):Thread獨(dú)享的start()方法先行于此線(xiàn)程的每一個(gè)動(dòng)作。
假定線(xiàn)程A在執(zhí)行過(guò)程中,通過(guò)執(zhí)行ThreadB.start()來(lái)啟動(dòng)線(xiàn)程B,那么線(xiàn)程A對(duì)共享變量的修改在接下來(lái)線(xiàn)程B開(kāi)始執(zhí)行后確保對(duì)線(xiàn)程B可見(jiàn)。

線(xiàn)程終止規(guī)則(Thread Termination Rule):線(xiàn)程中的每個(gè)操作都先行發(fā)生于對(duì)此線(xiàn)程的終止檢測(cè),我們可以通過(guò)Thread.join()方法結(jié)束、Thread.isAlive()的返回值檢測(cè)到線(xiàn)程已經(jīng)終止執(zhí)行。

線(xiàn)程中斷規(guī)則(Thread Interruption Rule):對(duì)線(xiàn)程interrupte()方法的調(diào)用優(yōu)先于被中斷線(xiàn)程的代碼檢測(cè)到中斷事件的發(fā)生,可以通過(guò)Thread.interrupted()方法檢測(cè)線(xiàn)程是否已中斷。

對(duì)象終結(jié)原則(Finalizer Rule):一個(gè)對(duì)象的初始化完成(構(gòu)造函數(shù)執(zhí)行結(jié)束)先行發(fā)生于它的finalize()方法的開(kāi)始。
假定線(xiàn)程A在執(zhí)行的過(guò)程中,通過(guò)制定ThreadB.join()等待線(xiàn)程B終止,那么線(xiàn)程B在終止之前對(duì)共享變量的修改在線(xiàn)程A等待返回后可見(jiàn)。

傳遞性(Transitivity):如果操作A先行發(fā)生于操作B,操作B先行發(fā)生于操作C,那就可以得出操作A先行發(fā)生于操作C的結(jié)論。
體現(xiàn)了happens-before原則具有傳遞性

如果不符合以上規(guī)則,那么在多線(xiàn)程環(huán)境下就不能保證執(zhí)行順序等同于代碼順序,也就是“如果在本線(xiàn)程中觀(guān)察,所有的操作都是有序的;如果在一個(gè)線(xiàn)程中觀(guān)察另外一個(gè)線(xiàn)程,則不符合以上規(guī)則的都是無(wú)序的”,因此,如果我們的多線(xiàn)程程序依賴(lài)于代碼書(shū)寫(xiě)順序,那么就要考慮是否符合以上規(guī)則,如果不符合就要通過(guò)一些機(jī)制使其符合,最常用的就是synchronized、Lock以及volatile修飾符。

上面八條是原生Java滿(mǎn)足Happens-before關(guān)系的規(guī)則,但是我們可以對(duì)他們進(jìn)行推導(dǎo)出其他滿(mǎn)足happens-before的規(guī)則:

將一個(gè)元素放入一個(gè)線(xiàn)程安全的隊(duì)列的操作Happens-Before從隊(duì)列中取出這個(gè)元素的操作

將一個(gè)元素放入一個(gè)線(xiàn)程安全容器的操作Happens-Before從容器中取出這個(gè)元素的操作

在CountDownLatch上的倒數(shù)操作Happens-Before CountDownLatch#await()操作

釋放Semaphore許可的操作Happens-Before獲得許可操作

Future表示的任務(wù)的所有操作Happens-Before Future#get()操作

向Executor提交一個(gè)Runnable或Callable的操作Happens-Before任務(wù)開(kāi)始執(zhí)行操作

happen-before原則是JMM中非常重要的原則,它是判斷數(shù)據(jù)是否存在競(jìng)爭(zhēng)、線(xiàn)程是否安全的主要依據(jù),保證了多線(xiàn)程環(huán)境下的可見(jiàn)性。

3. Volatile

volatile相當(dāng)于synchronized的弱實(shí)現(xiàn),類(lèi)似于synchronized的語(yǔ)義,但是沒(méi)有鎖機(jī)制。在JDK及開(kāi)源框架隨處可見(jiàn),但是在JDK6之后synchronized關(guān)鍵字性能被大幅優(yōu)化之后,幾乎沒(méi)有使用了場(chǎng)景。

3.1. 語(yǔ)義

第一條語(yǔ)義:JMM不會(huì)對(duì)volatile指令的操作進(jìn)行重排序。這個(gè)保證了對(duì)volatile變量的操作時(shí)按照指令的出現(xiàn)順序執(zhí)行的。

第二條語(yǔ)義是保證線(xiàn)程間變量的可見(jiàn)性,簡(jiǎn)單地說(shuō)就是當(dāng)線(xiàn)程A對(duì)變量X進(jìn)行了修改后,在線(xiàn)程A后面執(zhí)行的其他線(xiàn)程能看到變量X的變動(dòng),更詳細(xì)地說(shuō)是要符合以下兩個(gè)規(guī)則:

線(xiàn)程對(duì)變量進(jìn)行修改之后,要立刻回寫(xiě)到主內(nèi)存。

線(xiàn)程對(duì)變量讀取的時(shí)候,要從主內(nèi)存中讀,而不是緩存。

雖然volatile字段保證了可見(jiàn)性,但是由于缺少同步機(jī)制,所以volatile的字段的操作不是原子性的,并不能保證線(xiàn)程安全。

3.2. 應(yīng)用原則

volatile是在synchronized性能低下的時(shí)候提出的。如今synchronized的效率已經(jīng)大幅提升,所以volatile存在的意義不大。

如今非volatile的共享變量,在訪(fǎng)問(wèn)不是超級(jí)頻繁的情況下,已經(jīng)和volatile修飾的變量有同樣的效果了。

volatile不能保證原子性,這點(diǎn)是大家沒(méi)太搞清楚的,所以很容易出錯(cuò)。

volatile可以禁止重排序

通常應(yīng)用場(chǎng)景如下:

volatile boolean done = flase;
//...

while(!done){
   // ...
}
4. CAS 4.1. 鎖機(jī)制存在的問(wèn)題

在多線(xiàn)程競(jìng)爭(zhēng)下,加鎖、釋放鎖會(huì)導(dǎo)致比較多的上下文切換和調(diào)度延時(shí),引起性能問(wèn)題。

一個(gè)線(xiàn)程持有鎖會(huì)導(dǎo)致其它所有需要此鎖的線(xiàn)程掛起。

如果一個(gè)優(yōu)先級(jí)高的線(xiàn)程等待一個(gè)優(yōu)先級(jí)低的線(xiàn)程釋放鎖會(huì)導(dǎo)致優(yōu)先級(jí)倒置,引起性能風(fēng)險(xiǎn)。

獨(dú)占鎖是一種悲觀(guān)鎖,synchronized就是一種獨(dú)占鎖,會(huì)導(dǎo)致其它所有需要鎖的線(xiàn)程掛起,等待持有鎖的線(xiàn)程釋放鎖。而另一個(gè)更加有效的鎖就是樂(lè)觀(guān)鎖。所謂樂(lè)觀(guān)鎖就是,每次不加鎖而是假設(shè)沒(méi)有沖突而去完成某項(xiàng)操作,如果因?yàn)闆_突失敗就重試,直到成功為止。

4.2. 原理

CAS 操作包含三個(gè)操作數(shù)——內(nèi)存位置(V)、預(yù)期原值(A)和新值(B)。如果內(nèi)存位置的值與預(yù)期原值相匹配,那么處理器會(huì)自動(dòng)將該位置值更新為新值。否則,處理器不做任何操作。無(wú)論哪種情況,它都會(huì)在 CAS 指令之前返回該位置的值。(在 CAS 的一些特殊情況下將僅返回 CAS 是否成功,而不提取當(dāng)前值。)CAS 有效地說(shuō)明了“我認(rèn)為位置 V 應(yīng)該包含值 A;如果包含該值,則將 B 放到這個(gè)位置;否則,不要更改該位置,只告訴我這個(gè)位置現(xiàn)在的值即可?!?/p>

通常將 CAS 用于同步的方式是從地址 V 讀取值 A,執(zhí)行多步計(jì)算來(lái)獲得新值 B,然后使用 CAS 將 V 的值從 A 改為 B。如果 V 處的值尚未同時(shí)更改,則 CAS 操作成功。

CAS其底層是通過(guò)CPU的1條指令來(lái)完成3個(gè)步驟,因此其本身是一個(gè)原子性操作,不存在其執(zhí)行某一個(gè)步驟的時(shí)候而被中斷的可能。

從性能角度考慮:
如果使用鎖來(lái)進(jìn)行并發(fā)控制,當(dāng)某一個(gè)線(xiàn)程(T1)搶占到鎖之后,那么其他線(xiàn)程再?lài)L試去搶占鎖時(shí)就會(huì)被掛起,當(dāng)T1釋放鎖之后,下一個(gè)線(xiàn)程(T2)再搶占到鎖后并且重新恢復(fù)到原來(lái)的狀態(tài)大約需要經(jīng)過(guò)8W個(gè)時(shí)鐘周期。

假設(shè)我們業(yè)務(wù)代碼本身并不具備很復(fù)雜的操作,執(zhí)行整個(gè)操作可能就花費(fèi)3-10個(gè)時(shí)鐘周期左右,那么當(dāng)我們使用無(wú)鎖操作時(shí),線(xiàn)程T1和線(xiàn)程T2對(duì)共享變量進(jìn)行并發(fā)的CAS操作,假設(shè)T1成功了,T2最多再執(zhí)行一次,它執(zhí)行多次的所消耗的時(shí)間遠(yuǎn)遠(yuǎn)小于由于線(xiàn)程所掛起到恢復(fù)所消耗的時(shí)間,因此無(wú)鎖的CAS操作在性能上要比同步鎖高很多。

示例代碼:

public class SimulatedCAS {
     private int value;
 
     public synchronized int getValue() { return value; }
 
    public synchronized int compareAndSwap(int expectedValue, int newValue) {
         int oldValue = value;
         if (value == expectedValue)
             value = newValue;
         return oldValue;
     }
}

非阻塞算法:一個(gè)線(xiàn)程的失敗或者掛起不應(yīng)該影響其他線(xiàn)程的失敗或掛起的算法。

基于CAS的并發(fā)算法稱(chēng)為非阻塞算法,CAS 操作成功還是失敗,在任何一種情況中,它都在可預(yù)知的時(shí)間內(nèi)完成。如果 CAS 失敗,調(diào)用者可以重試 CAS 操作或采取其他適合的操作。下面顯示了重新編寫(xiě)的計(jì)數(shù)器類(lèi)來(lái)使用 CAS 替代鎖定:

public class CasCounter {
    private SimulatedCAS value;
    public int getValue() {
        return value.getValue();
    }
    public int increment() {
        int oldValue = value.getValue();
        while (value.compareAndSwap(oldValue, oldValue + 1) != oldValue)
            oldValue = value.getValue();
        return oldValue + 1;
    }
}

無(wú)論是直接的還是間接的,幾乎 java.util.concurrent 包中的所有類(lèi)都使用原子變量,而不使用同步。類(lèi)似 ConcurrentLinkedQueue 的類(lèi)也使用原子變量直接實(shí)現(xiàn)無(wú)等待算法,而類(lèi)似 ConcurrentHashMap 的類(lèi)使用 ReentrantLock 在需要時(shí)進(jìn)行鎖定。然后, ReentrantLock 使用原子變量來(lái)維護(hù)等待鎖定的線(xiàn)程隊(duì)列。

4.3. 缺陷

CAS策略有如下需要注意的事項(xiàng):

在線(xiàn)程搶占資源特別頻繁的時(shí)候(相對(duì)于CPU執(zhí)行效率而言),會(huì)造成長(zhǎng)時(shí)間的自旋,耗費(fèi)CPU性能。

有ABA問(wèn)題(即在更新前的值是A,但在操作過(guò)程中被其他線(xiàn)程更新為B,又更新為A),這時(shí)當(dāng)前線(xiàn)程認(rèn)為是可以執(zhí)行的,其實(shí)是發(fā)生了不一致現(xiàn)象,如果這種不一致對(duì)程序有影響(真正有這種影響的場(chǎng)景很少,除非是在變量操作過(guò)程中以此變量為標(biāo)識(shí)位做一些其他的事,比如初始化配置),則需要使用AtomicStampedReference(除了對(duì)更新前的原值進(jìn)行比較,也需要用更新前的stamp標(biāo)志位來(lái)進(jìn)行比較)。

只能對(duì)一個(gè)變量進(jìn)行原子性操作。如果需要把多個(gè)變量作為一個(gè)整體來(lái)做原子性操作,則應(yīng)該使用AtomicReference來(lái)把這些變量放在一個(gè)對(duì)象里,針對(duì)這個(gè)對(duì)象做原子性操作。

5. 引用

java的多線(xiàn)程機(jī)制引用

【死磕Java并發(fā)】-----Java內(nèi)存模型之happens-before

深入淺出 Java Concurrency (4): 原子操作 part 3 指令重排序與happens-before法則

流行的原子

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67708.html

相關(guān)文章

  • 阿里 2021 版最全 Java 并發(fā)編程筆記,看完我才懂了“內(nèi)卷”的真正意義

    摘要:純分享直接上干貨操作系統(tǒng)并發(fā)支持進(jìn)程管理內(nèi)存管理文件系統(tǒng)系統(tǒng)進(jìn)程間通信網(wǎng)絡(luò)通信阻塞隊(duì)列數(shù)組有界隊(duì)列鏈表無(wú)界隊(duì)列優(yōu)先級(jí)有限無(wú)界隊(duì)列延時(shí)無(wú)界隊(duì)列同步隊(duì)列隊(duì)列內(nèi)存模型線(xiàn)程通信機(jī)制內(nèi)存共享消息傳遞內(nèi)存模型順序一致性指令重排序原則內(nèi)存語(yǔ)義線(xiàn)程 純分享 , 直接上干貨! 操作系統(tǒng)并發(fā)支持 進(jìn)程管理內(nèi)存管...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 淺談Java并發(fā)編程系列(四)—— 原子性、可見(jiàn)性與有序性

    摘要:內(nèi)存模型是圍繞著在并發(fā)過(guò)程中如何處理原子性可見(jiàn)性和有序性這個(gè)特征來(lái)建立的,我們來(lái)看下哪些操作實(shí)現(xiàn)了這個(gè)特性。可見(jiàn)性可見(jiàn)性是指當(dāng)一個(gè)線(xiàn)程修改了共享變量的值,其他線(xiàn)程能夠立即得知這個(gè)修改。 Java內(nèi)存模型是圍繞著在并發(fā)過(guò)程中如何處理原子性、可見(jiàn)性和有序性這3個(gè)特征來(lái)建立的,我們來(lái)看下哪些操作實(shí)現(xiàn)了這3個(gè)特性。 原子性(atomicity): 由Java內(nèi)存模型來(lái)直接保證原子性變量操作包括...

    tianren124 評(píng)論0 收藏0
  • Java并發(fā)編程:從根源上解析volatile關(guān)鍵字的實(shí)現(xiàn)

    摘要:并發(fā)編程關(guān)鍵字解析解析概覽內(nèi)存模型的相關(guān)概念并發(fā)編程中的三個(gè)概念內(nèi)存模型深入剖析關(guān)鍵字使用關(guān)鍵字的場(chǎng)景內(nèi)存模型的相關(guān)概念緩存一致性問(wèn)題。事實(shí)上,這個(gè)規(guī)則是用來(lái)保證程序在單線(xiàn)程中執(zhí)行結(jié)果的正確性,但無(wú)法保證程序在多線(xiàn)程中執(zhí)行的正確性。 Java并發(fā)編程:volatile關(guān)鍵字解析 1、解析概覽 內(nèi)存模型的相關(guān)概念 并發(fā)編程中的三個(gè)概念 Java內(nèi)存模型 深入剖析volatile關(guān)鍵字 ...

    CNZPH 評(píng)論0 收藏0
  • Java并發(fā)編程的藝術(shù)】第二章讀書(shū)筆記之原子操作

    摘要:前言今天的筆記來(lái)了解一下原子操作以及中如何實(shí)現(xiàn)原子操作。概念原子本意是不能被進(jìn)一步分割的最小粒子,而原子操作意為不可被中斷的一個(gè)或一系列操作。處理器實(shí)現(xiàn)原子操作處理器會(huì)保證基本內(nèi)存操作的原子性。 showImg(https://segmentfault.com/img/bVVIRA?w=1242&h=536); 前言 今天的筆記來(lái)了解一下原子操作以及Java中如何實(shí)現(xiàn)原子操作。 概念 ...

    olle 評(píng)論0 收藏0
  • Java并發(fā)編程筆記(二)

    摘要:本文探討并發(fā)中的其它問(wèn)題線(xiàn)程安全可見(jiàn)性活躍性等等。當(dāng)閉鎖到達(dá)結(jié)束狀態(tài)時(shí),門(mén)打開(kāi)并允許所有線(xiàn)程通過(guò)。在從返回時(shí)被叫醒時(shí),線(xiàn)程被放入鎖池,與其他線(xiàn)程競(jìng)爭(zhēng)重新獲得鎖。 本文探討Java并發(fā)中的其它問(wèn)題:線(xiàn)程安全、可見(jiàn)性、活躍性等等。 在行文之前,我想先推薦以下兩份資料,質(zhì)量很高:極客學(xué)院-Java并發(fā)編程讀書(shū)筆記-《Java并發(fā)編程實(shí)戰(zhàn)》 線(xiàn)程安全 《Java并發(fā)編程實(shí)戰(zhàn)》中提到了太多的術(shù)語(yǔ)...

    NickZhou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<