java中並發包裏面的內容
1、CyclicBarrier
一個同步輔助類,允許一組線程相互等待,直到這組線程都到達某個公共屏障點。該barrier在釋放等待線程後可以重用,因此稱為循環的barrier。
來個示例:
package test;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Recipes_CyclicBarrier {
public static CyclicBarrier barrier = new CyclicBarrier(10);
public static void main(String[] args){
ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);
for(int i=1;i<=10;i++){
executor.submit(new Thread(new Runner(i+"號選手")));
}
executor.shutdown();
}
}
class Runner implements Runnable{
private String name;
public Runner(String name){
this.name = name;
}
@Override
public void run() {
System.out.println(name + "準備好了。");
try {
Recipes_CyclicBarrier.barrier.await(); //此處就是公共屏障點,所有線程到達之後,會釋放所有等待的線程
} catch (Exception e) {
}
System.out.println(name + "起跑!");
}
}
package test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
public static CountDownLatch countDownLatch = new CountDownLatch(10);//初始化計數值
public static void main(String[] args){
ExecutorService executor = Executors.newCachedThreadPool();//FixedThreadPool(10);
for(int i=1;i<=10;i++){
executor.submit(new Thread(new Runner1(i+"號選手")));
}
executor.shutdown();
}
}
class Runner1 implements Runnable{
private String name;
public Runner1(String name){
this.name = name;
}
@Override
public void run() {
System.out.println(name + "準備好了。");
CountDownLatchDemo.countDownLatch.countDown(); //計數值減1
try {
CountDownLatchDemo.countDownLatch.await();
} catch (Exception e) {
}
System.out.println(name + "起跑!");
}
}
2、CountDownLatch
CountDownLatch和CyclicBarrier有點類似,但是還是有些區別的。CountDownLatch也是一個同步輔助類,它允許一個或者多個線程一直等待,直到正在其他線程中執行的操作完成。它是等待正在其他線程中執行的操作,並不是線程之間相互等待。CountDownLatch初始化時需要給定一個計數值,每個線程執行完之後,必須調用countDown()方法使計數值減1,直到計數值為0,此時等待的線程才會釋放。
來個示例:
[java] view plain copy
3、CopyOnWriteArrayList & CopyOnWriteArraySet
CopyOnWriteArrayList & CopyOnWriteArraySet是並發容器,適合讀多寫少的場景,如網站的黑白名單設置。缺點是內存占用大,數據一致性的問題,CopyOnWrite容器只能保證數據最終的一致性,不能保證數據實時一致性。鑒於它的這些缺點,可以使用ConcurrentHashMap容器。
實現原理:新增到容器的數據會放到一個新的容器中,然後將原容器的引用指向新容器,舊容器也會存在,因此會有兩個容器占用內存。我們也可以用同樣的方式實現自己的CopyOnWriteMap。
4、ConcurrentHashMap
ConcurrentHashMap同樣是一個並發容器,將同步粒度最小化。
實現原理:ConcurrentHashMap默認是由16個Segment組成,每個Segment由多個Hashtable組成,數據變更需要經過兩次哈希算法,第一次哈希定位到Segment,第二次哈希定位到Segment下的Hashtable,容器只會將單個Segment鎖住,然後操作Segment下的Hashtable,多個Segment之間不受影響。如果需要擴容不是對Segment擴容而是對Segment下的Hashtable擴容。雖然經過兩次哈希算法會使效率降低,但是比鎖住整個容器效率要高得多。
5、BlockingQueue
BlockingQueue只是一個接口,它的實現類有ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、DelayQueue、LinkedBlockingDeque。
ArrayBlockingQueue:由數據支持的有界阻塞隊列。
LinkedBlockingQueue:基於鏈接節點、範圍任意的阻塞隊列。
PriorityBlockingQueue:無界阻塞隊列。
SynchronousQueue:一種阻塞隊列,其中每個插入操作必須等待另一個線程的對應移除操作。
DelayQueue:Delayed元素的一個無界阻塞隊列。
LinkedBlockingDeque:基於鏈接節點、範圍任意的雙端阻塞隊列,可以在隊列的兩端添加、移除元素。
6、Lock
Lock分為公平鎖和非公平鎖,默認是非公平鎖。實現類有ReetrantLock、ReetrantReadWriteLock,都依賴於AbstractQueuedSynchronizer抽象類。ReetrantLock將所有Lock接口的操作都委派到Sync類上,Sync有兩個子類:NonFairSync和FaiSync,通過其命名就能知道分別處理非公平鎖和公平鎖的。AbstractQueuedSynchronizer把所有請求構成一個CLH隊列,這裏是一個虛擬隊列,當有線程競爭鎖時,該線程會首先嘗試是否能獲取鎖,這種做法對於在隊列中等待的線程來說是非公平的,如果有線程正在Running,那麽通過循環的CAS操作將此線程增加到隊尾,直至添加成功。
7、Atomic包
Atomic包下的類實現了原子操作,有對基本類型如int、long、boolean實現原子操作的類:AtomicInteger、AtomicLong、AtomicBoolean,如果需要對一個對象進行原子操作,也有對對象引用進行原子操作的AtomicReference類,還有對對象數組操作的原子類:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。原子操作核心思想是CAS操作,然後調用底層操作系統指令來實現。
java中並發包裏面的內容