一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

多線程常見(jiàn)鎖策略+CAS介紹

Android編程精選 ? 來(lái)源:CSDN ? 2023-03-14 16:30 ? 次閱讀

一、樂(lè)觀鎖 & 悲觀鎖

1.1 樂(lè)觀鎖的定義

樂(lè)觀鎖,顧名思義,他比較樂(lè)觀,他認(rèn)為一般情況下不會(huì)出現(xiàn)沖突,所以只會(huì)在更新數(shù)據(jù)的時(shí)候才會(huì)對(duì)沖突進(jìn)行檢測(cè)。如果沒(méi)有發(fā)生沖突直接進(jìn)行修改,如果發(fā)生了沖突則不進(jìn)行任何修改,然后把結(jié)果返回給用戶,讓用戶自行處理。

1.1.1樂(lè)觀鎖的實(shí)現(xiàn)-CAS

樂(lè)觀鎖的實(shí)現(xiàn)并不是給數(shù)據(jù)加鎖 ,而是通過(guò)CAS(Compare And Swap)比較并替換,來(lái)實(shí)現(xiàn)樂(lè)觀鎖的效果。

CAS比較并替換的流程是這樣子的:CAS中包含了三個(gè)操作,單位:V(內(nèi)存值)、A(預(yù)期的舊址)、B(新值),比較V值和A值是否相等,,如果相等的話則將V的值更換成B,否則就提示用戶修改失敗,從而實(shí)現(xiàn)了CAS機(jī)制。

這只是定義的流程,但是在實(shí)際執(zhí)行過(guò)程中,并不會(huì)當(dāng)V值和A值不相等時(shí),就立即把結(jié)果返回給用戶,而是將A(預(yù)期的舊值)改為內(nèi)存中最新的值,然后再進(jìn)行比較,直到V值也A值相等,修改內(nèi)存中的值為B結(jié)束。

可能你還是覺(jué)得有些晦澀,那我們舉個(gè)栗子:

41ee6676-bf62-11ed-bfe3-dac502259ad0.png

看完這個(gè)圖相信你一定能理解了CAS的執(zhí)行流程了。

1.1.2 CAS的應(yīng)用

CAS的底層實(shí)現(xiàn)是靠Unsafe類實(shí)現(xiàn)的,Unsafe是CAS的核心類,由于Java方法無(wú)法直接訪問(wèn)底層系統(tǒng),需要通過(guò)本地(Native)方法來(lái)訪問(wèn),Unsafe相當(dāng)于一個(gè)后門(mén),基于該類可以直接操作特定的內(nèi)存數(shù)據(jù)。Unsafe類存在sun.misc包中,其內(nèi)部方法操作可以像C的指針一樣直接操作內(nèi)存,因?yàn)镴ava中的CAS操作的執(zhí)行依賴于Unsafe類的方法。

注意Unsafe類的所有方法都是native修飾的,也就是說(shuō)Unsafe類中的方法都直接調(diào)用操作系統(tǒng)底層資源執(zhí)行相應(yīng)的任務(wù)。因此不推薦使用Unsafe類,如果用不好會(huì)對(duì)底層資源造成影響。

為什么Atomic修飾的包裝類,能夠保證原子性,依靠的就是底層的unsafe類,我們來(lái)看看AtomicInteger的源碼:

41f6b146-bf62-11ed-bfe3-dac502259ad0.png

在getAndIncrement方法中還調(diào)用了unsafe的方法,因此這也就是為什么它能夠保證原子性的原因。

因此我們可以利用Atomic+包裝類實(shí)現(xiàn)線程安全的問(wèn)題。

importjava.util.concurrent.atomic.AtomicInteger;

/**
*使用AtomicInteger保證線程安全問(wèn)題
*/
publicclassAtomicIntegerDemo{
staticclassCounter{
privatestaticAtomicIntegernum=newAtomicInteger(0);
privateintMAX_COUNT=100000;
publicCounter(intMAX_COUNT){
this.MAX_COUNT=MAX_COUNT;
}
//++方法
publicvoidincrement(){
for(inti=0;i{
counter.increment();
});
Threadthread2=newThread(()->{
counter.decrement();
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("最終結(jié)果:"+counter.getNum());
}
}
4207dbe2-bf62-11ed-bfe3-dac502259ad0.png

1.1.3 CAS存在的問(wèn)題

循環(huán)時(shí)間長(zhǎng),開(kāi)銷大

只能保證一個(gè)共享變量的原子性操作(可以通過(guò)循環(huán)CAS的方式實(shí)現(xiàn))

存在ABA問(wèn)題

1.1.4 ABA問(wèn)題

什么時(shí)ABA問(wèn)題呢?

比如說(shuō)兩個(gè)線程t1和t2,t1的執(zhí)行時(shí)間為10s,t2的執(zhí)行時(shí)間為2s,剛開(kāi)始都從主內(nèi)存中獲取到A值,t2先開(kāi)始執(zhí)行,他執(zhí)行的比較快,于是他將A的值先改為B,再改為A,這時(shí)t1執(zhí)行,判斷內(nèi)存中的值為A,與自己預(yù)期的值一樣,以為這個(gè)值沒(méi)有修改過(guò),于是將內(nèi)存中的值修改為B,但是實(shí)際上中間可能已經(jīng)經(jīng)歷了許多:A->B->A。

所以ABA問(wèn)題就是,在我們進(jìn)行CAS中的比較時(shí),預(yù)期的值與內(nèi)存中的值一樣,并不能說(shuō)明這個(gè)值沒(méi)有被改過(guò),而是可能已經(jīng)被修改了,但是又被改回了預(yù)期的值。

importjava.util.concurrent.atomic.AtomicInteger;

/**
*ABA問(wèn)題演示
*/
publicclassABADemo1{
privatestaticAtomicIntegermoney=newAtomicInteger(100);
publicstaticvoidmain(String[]args)throwsInterruptedException{
//第一次點(diǎn)轉(zhuǎn)賬按鈕(-50)
Threadt1=newThread(()->{
intold_money=money.get();//先得到余額
try{//執(zhí)行花費(fèi)2s
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
money.compareAndSet(old_money,old_money-50);
});
t1.start();

//第二次點(diǎn)擊轉(zhuǎn)賬按鈕(-50)不小心點(diǎn)擊的,因?yàn)榈谝淮吸c(diǎn)擊之后沒(méi)反應(yīng),所以不小心又點(diǎn)了一次
Threadt2=newThread(()->{
intold_money=money.get();//先得到余額
money.compareAndSet(old_money,old_money-50);
});
t2.start();

//給賬戶加50
Threadt3=newThread(()->{
//執(zhí)行花費(fèi)1s
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
intold_money=money.get();
money.compareAndSet(old_money,old_money+50);

});
t3.start();

t1.join();
t2.join();
t3.join();
System.out.println("最終的錢(qián)數(shù):"+money.get());
}
}
42189b62-bf62-11ed-bfe3-dac502259ad0.png

這個(gè)例子演示了ABA問(wèn)題,A有100元,A向B轉(zhuǎn)錢(qián),第一次轉(zhuǎn)了50元,但是點(diǎn)完轉(zhuǎn)賬按鈕沒(méi)有反應(yīng),于是又點(diǎn)擊了一次。第一次轉(zhuǎn)賬成功后A還剩50元,而這時(shí)C給A轉(zhuǎn)了50元,A的余額變?yōu)?00元,第二次的CAS判斷(100,100,50),A的余額與預(yù)期的值一樣,于是將A的余額修改為50元。

1.1.5 ABA問(wèn)題的解決方案

由于CAS是只管頭和尾是否相等,若相等,就認(rèn)為這個(gè)過(guò)程沒(méi)問(wèn)題,因此我們就引出了AtomicStampedReference,時(shí)間戳原子引用,在這里應(yīng)用于版本號(hào)的更新。也就是我們新增了一種機(jī)制,在每次更新的時(shí)候,需要比較當(dāng)前值和期望值以及當(dāng)前版本號(hào)和期望版本號(hào),若值或版本號(hào)有一個(gè)不相同,這個(gè)過(guò)程都是有問(wèn)題的。

我們來(lái)看上面的例子怎么用AtomicStampedReference解決呢?

importjava.util.concurrent.atomic.AtomicInteger;
importjava.util.concurrent.atomic.AtomicStampedReference;

/**
*ABA問(wèn)題解決添加版本號(hào)
*/
publicclassABADemo2{
privatestaticAtomicStampedReferencemoney=
newAtomicStampedReference<>(100,0);
publicstaticvoidmain(String[]args)throwsInterruptedException{
//第一次點(diǎn)轉(zhuǎn)賬按鈕(-50)
Threadt1=newThread(()->{
intold_money=money.getReference();//先得到余額100
intoldStamp=money.getStamp();//得到舊的版本號(hào)
try{//執(zhí)行花費(fèi)2s
Thread.sleep(2000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
booleanresult=money.compareAndSet(old_money,old_money-50,oldStamp,oldStamp+1);
System.out.println(Thread.currentThread().getName()+"轉(zhuǎn)賬:"+result);
},"線程1");
t1.start();

//第二次點(diǎn)擊轉(zhuǎn)賬按鈕(-50)不小心點(diǎn)擊的,因?yàn)榈谝淮吸c(diǎn)擊之后沒(méi)反應(yīng),所以不小心又點(diǎn)了一次
Threadt2=newThread(()->{
intold_money=money.getReference();//先得到余額100
intoldStamp=money.getStamp();//得到舊的版本號(hào)
booleanresult=money.compareAndSet(old_money,old_money-50,oldStamp,oldStamp+1);
System.out.println(Thread.currentThread().getName()+"轉(zhuǎn)賬:"+result);
},"線程2");
t2.start();

//給賬戶+50
Threadt3=newThread(()->{
//執(zhí)行花費(fèi)1s
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
intold_money=money.getReference();//先得到余額100
intoldStamp=money.getStamp();//得到舊的版本號(hào)
booleanresult=money.compareAndSet(old_money,old_money+50,oldStamp,oldStamp+1);
System.out.println(Thread.currentThread().getName()+"發(fā)工資:"+result);

},"線程3");
t3.start();

t1.join();
t2.join();
t3.join();
System.out.println("最終的錢(qián)數(shù):"+money.getReference());
}
}
422cd712-bf62-11ed-bfe3-dac502259ad0.png

AtommicStampedReference解決了ABA問(wèn)題,在每次更新值之前,比較值和版本號(hào)。

1.2 悲觀鎖

什么是悲觀鎖?

悲觀鎖就是比較悲觀,總是假設(shè)最壞的情況,每次去拿數(shù)據(jù)的時(shí)候都會(huì)認(rèn)為別人會(huì)修改,所以在每次拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿數(shù)據(jù)就會(huì)阻塞直到它拿到鎖。

比如我們之前提到的synchronized和Lock都是悲觀鎖。

二、公平鎖和非公平鎖

公平鎖: 按照線程來(lái)的先后順序獲取鎖,當(dāng)一個(gè)線程釋放鎖之后,那么就喚醒阻塞隊(duì)列中第一個(gè)線程獲取鎖。

4235bb02-bf62-11ed-bfe3-dac502259ad0.png

非公平鎖: 不是按照線程來(lái)的先后順序喚醒鎖,而是當(dāng)有一個(gè)線程釋放鎖之后,喚醒阻塞隊(duì)列中的所有線程,隨機(jī)獲取鎖。

424aa724-bf62-11ed-bfe3-dac502259ad0.png

之前在講synchronized和Lock這兩個(gè)鎖解決線程安全問(wèn)題線程安全問(wèn)題的解決的時(shí)候,我們提過(guò):

synchronized的鎖只能是非公平鎖;

Lock的鎖默認(rèn)情況下是非公平鎖,而擋在構(gòu)造 函數(shù)中傳入?yún)?shù)時(shí),則是公平鎖;

公平鎖:Lock lock=new ReentrantLock(true);

非公平鎖:Lock lock=new ReentrantLock();

由于公平鎖只能按照線程來(lái)的線程順序獲取鎖,因此性能較低,推薦使用非公平鎖。

三、讀寫(xiě)鎖

3.1 讀寫(xiě)鎖

讀寫(xiě)鎖顧名思義是一把鎖分為兩部分:讀鎖和寫(xiě)鎖。

讀寫(xiě)鎖的規(guī)則是:允許多個(gè)線程獲取讀鎖,而寫(xiě)鎖是互斥鎖,不允許多個(gè)線程同時(shí)獲得,并且讀操作和寫(xiě)操作也是 互斥的,總的來(lái)說(shuō)就是讀讀不互斥,讀寫(xiě)互斥,寫(xiě)寫(xiě)互斥。

為什么要這樣設(shè)置呢?

讓整個(gè)讀寫(xiě)的操作到設(shè)置為互斥不是更方便嗎?

其實(shí)只要涉及到“互斥”,就會(huì)產(chǎn)生線程掛起等待,一旦掛起等待,,再次被喚醒就不知道什么時(shí)候了,因此盡可能的減少“互斥"的機(jī)會(huì),就是提高效率的重要途徑。

Java標(biāo)準(zhǔn)庫(kù)提供了ReentrantReadWriteLock類實(shí)現(xiàn)了讀寫(xiě)鎖。

ReentrantReadWriteLock.ReadLock類表示一個(gè)讀鎖,提供了lock和unlock進(jìn)行加鎖和解鎖。

ReentrantReadWriteLock.WriteLock類表示一個(gè)寫(xiě)鎖,提供了lock和unlock進(jìn)行加鎖和解鎖。

下面我們來(lái)看下讀寫(xiě)鎖的使用演示~

importjava.time.LocalDateTime;
importjava.util.concurrent.LinkedBlockingDeque;
importjava.util.concurrent.ThreadPoolExecutor;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.locks.ReentrantReadWriteLock;

/**
*演示讀寫(xiě)鎖的使用
*/
publicclassReadWriteLockDemo1{
publicstaticvoidmain(String[]args){
//創(chuàng)建讀寫(xiě)鎖
finalReentrantReadWriteLockreentrantReadWriteLock=newReentrantReadWriteLock();
//創(chuàng)建讀鎖
finalReentrantReadWriteLock.ReadLockreadLock=reentrantReadWriteLock.readLock();
//創(chuàng)建寫(xiě)鎖
finalReentrantReadWriteLock.WriteLockwriteLock=reentrantReadWriteLock.writeLock();
//線程池
ThreadPoolExecutorexecutor=newThreadPoolExecutor(5,5,0,TimeUnit.SECONDS,newLinkedBlockingDeque<>(100));
//啟動(dòng)線程執(zhí)行任務(wù)【讀操作1】
executor.submit(()->{
//加鎖操作
readLock.lock();
try{
//執(zhí)行業(yè)務(wù)邏輯
System.out.println("執(zhí)行讀鎖1:"+LocalDateTime.now());
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
readLock.unlock();
}
});

//啟動(dòng)線程執(zhí)行任務(wù)【讀操作2】
executor.submit(()->{
//加鎖操作
readLock.lock();
try{
//執(zhí)行業(yè)務(wù)邏輯
System.out.println("執(zhí)行讀鎖2:"+LocalDateTime.now());
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
//釋放鎖
readLock.unlock();
}
});

//啟動(dòng)線程執(zhí)行【寫(xiě)操作1】
executor.submit(()->{
//加鎖
writeLock.lock();
try{
System.out.println("執(zhí)行寫(xiě)鎖1:"+LocalDateTime.now());
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
writeLock.unlock();
}
});

//啟動(dòng)線程執(zhí)行【寫(xiě)操作2】
executor.submit(()->{
//加鎖
writeLock.lock();
try{
System.out.println("執(zhí)行寫(xiě)鎖2:"+LocalDateTime.now());
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedExceptione){
e.printStackTrace();
}finally{
writeLock.unlock();
}
});
}
}
426afbbe-bf62-11ed-bfe3-dac502259ad0.png

根據(jù)運(yùn)行結(jié)果我們看到,讀鎖操作是一起執(zhí)行的,而寫(xiě)鎖操作是互斥執(zhí)行的。

3.2 獨(dú)占鎖

獨(dú)占鎖就是指任何時(shí)候只能有一個(gè)線程能執(zhí)行資源操作,是互斥的。

比如寫(xiě)鎖,就是一個(gè)獨(dú)占鎖,任何時(shí)候只能有一個(gè)線程執(zhí)行寫(xiě)操作,synchronized、Lock都是獨(dú)占鎖。

3.3 共享鎖

共享鎖是指可以同時(shí)被多個(gè)線程獲取,但是只能被一個(gè)線程修改。讀寫(xiě)鎖就是一個(gè)典型的共享鎖,它允許多個(gè)線程進(jìn)行讀操作 ,但是只允許一個(gè)線程進(jìn)行寫(xiě)操作。

四、可重入鎖 & 自旋鎖

4.1 可重入鎖

可重入鎖指的是該線程獲取了該鎖之后,可以無(wú)限次的進(jìn)入該鎖。

因?yàn)樵趯?duì)象頭存儲(chǔ)了擁有當(dāng)前鎖的id,進(jìn)入鎖之前驗(yàn)證對(duì)象頭的id是否與當(dāng)前線程id一致,若一致就可進(jìn)入,因此實(shí)現(xiàn)可重入鎖 。

4.2 自旋鎖

自旋鎖是指嘗試獲取鎖的線程不會(huì)立即阻塞,而是采取循環(huán)的方式嘗試獲取鎖,這樣的好處是減少線程上下文切換的消耗。線程上下文切換就是從用戶態(tài)—>內(nèi)核態(tài)。

synchronized就是一種自適應(yīng)自旋鎖(自旋的次數(shù)不固定),hotSpot虛擬機(jī)的自旋機(jī)制是這一次的自旋次數(shù)由上一次自旋獲取鎖的次數(shù)來(lái)決定,如果上次自旋了很多次才獲取到鎖,那么這次自旋的次數(shù)就會(huì)降低,因?yàn)樘摂M機(jī)認(rèn)為這一次大概率還是要自旋很多次才能獲取到鎖,比較浪費(fèi)系統(tǒng)資源。




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 虛擬機(jī)
    +關(guān)注

    關(guān)注

    1

    文章

    955

    瀏覽量

    28886
  • CAS
    CAS
    +關(guān)注

    關(guān)注

    0

    文章

    35

    瀏覽量

    15329
  • ABAT
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    6333

原文標(biāo)題:一篇文章搞定,多線程常見(jiàn)鎖策略+CAS

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    Java多線程的用法

    本文將介紹一下Java多線程的用法。 基礎(chǔ)介紹 什么是多線程 指的是在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)線程,每個(gè)
    的頭像 發(fā)表于 09-30 17:07 ?1106次閱讀

    C++面向?qū)ο?b class='flag-5'>多線程編程 (pdf電子版)

    C++面向?qū)ο?b class='flag-5'>多線程編程共分13章,全面講解構(gòu)建多線程架構(gòu)與增量多線程編程技術(shù)。第1章介紹
    發(fā)表于 09-25 09:39 ?0次下載

    QNX環(huán)境下多線程編程

    介紹了QNX 實(shí)時(shí)操作系統(tǒng)和多線程編程技術(shù),包括線程間同步的方法、多線程程序的分析步驟、線程基本程序結(jié)構(gòu)以及實(shí)用編譯方法。QNX 是由加拿大
    發(fā)表于 08-12 17:37 ?30次下載

    多線程技術(shù)在串口通信中的應(yīng)用

            首先介紹多線程技術(shù)的基本原理,然后討論了多線程技術(shù)在串口通信中的應(yīng)用,并給出了實(shí)現(xiàn)的方法和步驟。關(guān)鍵詞:
    發(fā)表于 09-04 09:10 ?18次下載

    多線程細(xì)節(jié)問(wèn)題學(xué)習(xí)筆記

    這一次我們要說(shuō)下關(guān)于final在多線程的作用,原子性的使用,死鎖以及Java中的應(yīng)對(duì)方案,線程的局部變量 和 讀寫(xiě)介紹 。關(guān)于final變量在
    發(fā)表于 11-28 15:34 ?1220次閱讀
    <b class='flag-5'>多線程</b>細(xì)節(jié)問(wèn)題學(xué)習(xí)筆記

    多線程好還是單線程好?單線程多線程的區(qū)別 優(yōu)缺點(diǎn)分析

    摘要:如今單線程多線程已經(jīng)得到普遍運(yùn)用,那么到底多線程好還是單線程好呢?單線程多線程的區(qū)別又
    發(fā)表于 12-08 09:33 ?8.2w次閱讀

    mfc多線程編程實(shí)例及代碼,mfc多線程間通信介紹

    摘要:本文主要以MFC多線程為中心,分別對(duì)MFC多線程的實(shí)例、MFC多線程之間的通信展開(kāi)的一系列研究,下面我們來(lái)看看原文。
    發(fā)表于 12-08 15:23 ?1.8w次閱讀
    mfc<b class='flag-5'>多線程</b>編程實(shí)例及代碼,mfc<b class='flag-5'>多線程</b>間通信<b class='flag-5'>介紹</b>

    什么是多線程編程?多線程編程基礎(chǔ)知識(shí)

    摘要:多線程編程是現(xiàn)代軟件技術(shù)中很重要的一個(gè)環(huán)節(jié)。要弄懂多線程,這就要牽涉到多進(jìn)程。本文主要以多線程編程以及多線程編程相關(guān)知識(shí)而做出的一些結(jié)論。
    發(fā)表于 12-08 16:30 ?1.3w次閱讀

    java學(xué)習(xí)——java面試【事務(wù)、多線程】資料整理

    本文檔內(nèi)容介紹了基于java學(xué)習(xí)java面試【事務(wù)、、多線程】資料整理,供參考
    發(fā)表于 03-13 13:53 ?0次下載

    多線程編程指南的PDF電子書(shū)免費(fèi)下載

    多線程編程指南》介紹了 SolarisTM 操作系統(tǒng) (Solaris Operating System, Solaris OS)中 POSIX?線程和 Solaris 線程
    發(fā)表于 06-11 08:00 ?4次下載
    <b class='flag-5'>多線程</b>編程指南的PDF電子書(shū)免費(fèi)下載

    無(wú)CAS如何實(shí)現(xiàn)各種無(wú)的數(shù)據(jù)結(jié)構(gòu)

    ,可用于在多線程編程中實(shí)現(xiàn)不被打斷的數(shù)據(jù)交換操作,從而避免多線程同時(shí)改寫(xiě)某?數(shù)據(jù)時(shí)由于執(zhí)行順序不確定性以及中斷的不可預(yù)知性產(chǎn)?的數(shù)據(jù)不一致問(wèn)題 有了CAS,我們就可以用它來(lái)實(shí)現(xiàn)各種無(wú)
    的頭像 發(fā)表于 11-13 15:38 ?1083次閱讀
    無(wú)<b class='flag-5'>鎖</b><b class='flag-5'>CAS</b>如何實(shí)現(xiàn)各種無(wú)<b class='flag-5'>鎖</b>的數(shù)據(jù)結(jié)構(gòu)

    多線程同步的幾種方法

    多線程同步是指在多個(gè)線程并發(fā)執(zhí)行的情況下,為了保證線程執(zhí)行的正確性和一致性,需要采用特定的方法來(lái)協(xié)調(diào)線程之間的執(zhí)行順序和共享資源的訪問(wèn)。下面將介紹
    的頭像 發(fā)表于 11-17 14:16 ?1466次閱讀

    多線程如何保證數(shù)據(jù)的同步

    。本文將詳細(xì)介紹多線程數(shù)據(jù)同步的概念、問(wèn)題、以及常見(jiàn)的解決方案。 一、多線程數(shù)據(jù)同步概念 在多線程編程中,數(shù)據(jù)同步指的是通過(guò)某種機(jī)制來(lái)確保多
    的頭像 發(fā)表于 11-17 14:22 ?1525次閱讀

    mfc多線程編程實(shí)例

    (圖形用戶界面)應(yīng)用程序的開(kāi)發(fā)。在這篇文章中,我們將重點(diǎn)介紹MFC中的多線程編程。 多線程編程在軟件開(kāi)發(fā)中非常重要,它可以實(shí)現(xiàn)程序的并發(fā)執(zhí)行,提高程序的效率和響應(yīng)速度。MFC提供了豐富的多線程
    的頭像 發(fā)表于 12-01 14:29 ?1761次閱讀

    java實(shí)現(xiàn)多線程的幾種方式

    了多種實(shí)現(xiàn)多線程的方式,本文將詳細(xì)介紹以下幾種方式: 1.繼承Thread類 2.實(shí)現(xiàn)Runnable接口 3.Callable和Future 4.線程池 5.Java 8中
    的頭像 發(fā)表于 03-14 16:55 ?985次閱讀