并發(fā)的學(xué)習(xí)與使用
通過(guò)單例模式理解synchronized,volatile
上兩篇主要是常見(jiàn)的關(guān)于并發(fā)的一些知識(shí)剥啤,本篇將介紹一些自己平常不常用的一些并發(fā)相關(guān)的內(nèi)容罩阵。
單例模式的一種新的方式
最近在讀RxJava的源碼時(shí),見(jiàn)到了一種新的單例模式,可能是自己見(jiàn)識(shí)太少,之前對(duì)這種方式真的沒(méi)見(jiàn)過(guò),也可以說(shuō)聞所未聞渤早。由此引發(fā)了一些對(duì)Atomic**相關(guān)原子類的思考的研究,先看代碼:
public class Singleton {
private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();
private Singleton (){}
public static Singleton getInstance() {
for (;;) {
Singleton current = INSTANCE.get();
if (current != null) {
return current;
}
current = new Singleton();
if (INSTANCE.compareAndSet(null, current)) {
return current;
}
}
}
}
先看下AtomicReference的源碼:
AtomicReference是作用是對(duì)"對(duì)象"進(jìn)行原子操作瘫俊。通過(guò)源碼可以看出鹊杖,它是通過(guò)"volatile"和"Unsafe提供的CAS(比較與交換,Compare and swap,是一種有名的無(wú)鎖算法函數(shù))實(shí)現(xiàn)原子操作扛芽。
- current是volatile類型骂蓖。這保證了:當(dāng)某線程修改value的值時(shí),其他線程看到的value值都是最新的value值川尖,即修改之后的volatile的值登下。
- 通過(guò)CAS設(shè)置value。這保證了:當(dāng)某線程池通過(guò)CAS函數(shù)(如compareAndSet函數(shù))設(shè)置value時(shí)叮喳,它的操作是原子的被芳,即線程在操作value時(shí)不會(huì)被中斷。CAS是一種無(wú)阻塞的鎖,采用不斷比較設(shè)值的方式來(lái)避免并發(fā)問(wèn)題,不會(huì)有鎖的等待和上下文切換問(wèn)題,性能消耗較小馍悟。
如果當(dāng)前值 == 預(yù)期值畔濒,則以原子方式將該值設(shè)置為給定的更新值。
這種方式既能夠保證延遲加載又能保證原子性及實(shí)例的唯一性锣咒,代碼也相對(duì)比較簡(jiǎn)潔侵状。
通過(guò)并發(fā)的學(xué)習(xí)與使用,線程的阻塞和上下文的切換會(huì)帶來(lái)一定的性能開(kāi)銷毅整,尤其在高并發(fā)的環(huán)境下趣兄。
而原子變量可以避免優(yōu)先級(jí)倒置和死鎖等危險(xiǎn),競(jìng)爭(zhēng)比較便宜毛嫉,協(xié)調(diào)發(fā)生在更細(xì)的粒度級(jí)別诽俯,允許更高程度的并行機(jī)制等等