并發(fā)是一種能并行運(yùn)行多個(gè)程序或并行運(yùn)行一個(gè)程序中多個(gè)部分的能力。如果程序中一個(gè)耗時(shí)的任務(wù)能以異步或并行的方式運(yùn)行,那么整個(gè)程序的吞吐量和可交互性將大大改善。現(xiàn)代的PC都有多個(gè)CPU或一個(gè)CPU中有多個(gè)核,是否能合理運(yùn)用多核的能力將成為一個(gè)大規(guī)模應(yīng)用程序的關(guān)鍵。
Java基礎(chǔ)部分知識(shí)總結(jié)點(diǎn)擊Java并發(fā)基礎(chǔ)總結(jié)。Java多線程相關(guān)類的實(shí)現(xiàn)都在Java的并發(fā)包c(diǎn)oncurrent,concurrent包主要包含3部分內(nèi)容,第一個(gè)是atomic包,里面主要是一些原子類,比如AtomicInteger、AtomicIntegerArray等;第二個(gè)是locks包,里面主要是鎖相關(guān)的類,比如ReentrantLock、Condition等;第三個(gè)就是屬于concurrent包的內(nèi)容,主要包括線程池相關(guān)類(Executors)、阻塞集合類(BlockingQueue)、并發(fā)Map類(ConcurrentHashMap)、線程相關(guān)類(Thread、Runnable、Callable)等。
atomic包源碼分析
atomic包是專門為線程安全設(shè)計(jì)的Java包,包含多個(gè)原子操作類。其基本思想就是在多線程環(huán)境下,當(dāng)有多個(gè)線程同時(shí)執(zhí)行這些類的實(shí)例的方法時(shí),具有排他性,一個(gè)線程進(jìn)入方法執(zhí)行指令時(shí),不會(huì)被其他的線程打斷,而別的線程就像自旋鎖一樣,一直等待該方法執(zhí)行完成。
原子變量的底層使用了處理器提供的原子指令,但是不同的CPU架構(gòu)可能提供的原子指令不一樣,也有可能需要某種形式的內(nèi)部鎖,所以該方法不能絕對(duì)保證線程不被阻塞。
atomic包一共有12個(gè)類,四種原子更新方式,分別是原子更新基本類型、原子更新數(shù)組、原子更新引用和原子更新字段。JDK1.5中引入了底層的支持,在int、long和對(duì)象的引用等類型上都公開了CAS的操作,并且JVM把它們編譯為底層硬件提供的最有效的方法,在運(yùn)行CAS的平臺(tái)上,運(yùn)行時(shí)把它們編譯為相應(yīng)的機(jī)器指令。在java.util.concurrent.atomic包下面的所有的原子變量類型中,比如AtomicInteger,都使用了這些底層的JVM支持為數(shù)字類型的引用類型提供一種高效的CAS操作。
Unsafe中的操作一般都是基于CAS來實(shí)現(xiàn)的,CAS就是Compare and Swap的意思,比較并操作。很多的cpu直接支持CAS指令。CAS是一項(xiàng)樂觀鎖技術(shù),當(dāng)多個(gè)線程嘗試使用CAS同時(shí)更新同一個(gè)變量時(shí),只有其中一個(gè)線程能更新變量的值,而其它線程都失敗,失敗的線程并不會(huì)被掛起,而是被告知這次競(jìng)爭(zhēng)中失敗,并可以再次嘗試。CAS有3個(gè)操作數(shù),內(nèi)存值V,舊的預(yù)期值A(chǔ),要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時(shí),將內(nèi)存值V修改為B,否則什么都不做。