· 1. 等待多線程完成的CountDownLatch
構造函數接收一個int類型的參數作為計數器,如果想等待N個點,就傳入N。當調用CountDownLatch的countDown方法時,N就會減一,直至減為零。使用await方法等待,當N的值變為零,執行await的線程繼續執行。
public class CountDownTest {
static CountDownLatch c = new CountDownLatch(2);
static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String agrs[]){
pool.execute(new Runnable() {
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(3);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("This is A");
c.countDown();
}
});
pool.execute(new Runnable() {
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(3);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("This is B");
c.countDown();
}
});
try {
c.await();
}catch (InterruptedException e){
}
System.out.println("This is main");
}
}
2. 同步屏障CyclicBarrier
可循環使用的屏障。它要做的事情,讓一組線程到達屏障時被阻塞,直到最后一個線程到達屏障時,屏障才會打開,所有被屏障攔截的線程才會繼續運行。
默認構造方法CyclicBarrier(int parties),其參數表示屏障攔截的線程數,每個線程調用await方法告訴CyclicBarrier已經到達屏障,然后當前線程阻塞。
public class CylicBarrierTest {
static CyclicBarrier c = new CyclicBarrier(2);
static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String args[]){
pool.execute(new Runnable() {
public void run() {
System.out.println("this is A");
try {
c.await();
System.out.println("this is Aa");
}catch (Exception e){
e.printStackTrace();
}
}
});
pool.execute(new Runnable() {
public void run() {
System.out.println("this is B");
try {
c.await();
System.out.println("this is Bb");
}catch (Exception e){
e.printStackTrace();
}
}
});
pool.shutdown();
}
}
3. CountDownLatch vs CyclicBarrier
CountDownLatch的計數器只使用一次,而CyclicBarrier的計數器可以使用reset方法重置,重復使用
4. 控制線程並發數的信號量 Semaphore
控制有限哥線程使用資源。使用方法 Semaphore ss = new Semaphore(N), N表示最大的並發量,每個線程使用資源前調用ss.acquire()方法獲取權限,使用完后調用ss.release()方法釋放權限。
5. 線程間的數據交換Exchanger
它提供一個同步點,在這個同步點,兩個線程可以交換彼此的數據。
public class ExchangeTest {
private static final Exchanger<String> exgr = new Exchanger<String>();
private static ExecutorService pool = Executors.newFixedThreadPool(2);
public static void main(String args[]){
pool.execute(new Runnable() {
public void run() {
String A = "銀行流水A";
try {
A = exgr.exchange(A);
System.out.println("A 當前的值:" + A);
}catch (InterruptedException e){
}
}
});
pool.execute(new Runnable() {
public void run() {
String B = "銀行流水B";
try {
B = exgr.exchange(B);
System.out.println("B 當前的值:" + B);
}catch (InterruptedException e){
}
}
});
pool.shutdown();
}