《java併發程式設計的藝術》併發工具類
CountDownLatch
join:
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
Thread parser1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("parser1 finish");
}
});
Thread parser2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("parser2 finish");
}
});
parser1.start();
parser2.start();
parser1.join();
parser1.join();
System.out.println("all parser finish");
}
}
countDownLatch:
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(1);
c.countDown();
System.out.println(2);
c.countDown();
}
}).start();
c.await();
System.out.println(3);
}
}
建構函式接收一個int型別的引數作為計數器,該引數作為等待的次數。
當我們呼叫countDown方法時,該引數減1,CountDownLatch的await方法會阻塞當前執行緒,直到引數為0.
await有一個帶指定時間的方法:await(long time,TimeUnit unit);
CyclicBarrier
CyclicBarrier的字面意思是可迴圈的屏障。讓一組執行緒到達一個屏障時被阻塞,直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續執行。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
static CyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(1);
}
});
thread.start();
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(2);
}
}
CyclicBarrier預設的構造方法是CyclicBarrier(int partier),其參數列示屏障攔截的執行緒數量,每個執行緒呼叫await方法告訴CyclicBarrier我已經到達屏障了,然後當前執行緒被阻塞。直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續執行。
CyclicBarrier還有一個建構函式CyclicBarrier(int parties,Runnable barrierAction),用於執行緒到達屏障時,優先執行barrierAction。
static CyclicBarrier c = new CyclicBarrier(5, new Before());
public static void main(String[] args) {
Runnable r = () -> {
System.out.println("i am a thread");
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
};
Thread[] threads = new Thread[4];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(r);
threads[i].start();
}
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("over");
}
static class Before implements Runnable {
@Override
public void run() {
System.out.println("i am out of barrier");
}
}
執行結果:
i am a thread
i am a thread
i am a thread
i am a thread
i am out of barrier
over
CyclicBarrier的計數器可以使用reset()方法重置。
Semaphore
Semaphore訊號量用來控制同時訪問特定資源的執行緒數量,它通過協調各個執行緒,保證合理的使用公共資源。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
public static final int THREAD_COUNT = 30;
private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
private static Semaphore s = new Semaphore(10);
public static void main(String[] args){
for (int i = 0; i < THREAD_COUNT; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
s.acquire();
System.out.println("save data");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
threadPool.shutdown();
}
}
訊號量可以用來控制併發量。首先執行緒使用Semaphore的acquire()方法獲得一個許可證,使用完後呼叫release()方法歸還許可證,擁有許可證的執行緒才可以執行。
Exchanger
Exchanger是一個執行緒間協作的工具類。提供了一個同步點,在這個同步點,兩個執行緒可以交換彼此的資料。當第一個執行緒執行exchange()方法,它會一直等待第二個執行緒也執行exchange()方法,當兩個執行緒都到達同步點時,執行緒可以交換資料。
Exchanger可以用於遺傳演算法,遺傳演算法需要選出兩個人作為交配物件,這時候交換兩個人的資料,並使用交叉規則得出2個交配結果。Exchanger也可以用於校對工作。
import java.util.concurrent.Exchanger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExchangerTest {
private static final Exchanger<String> ex = new Exchanger<>();
private static ExecutorService threadPool = Executors.newFixedThreadPool(2);
public static void main(String[] args){
threadPool.execute(()->{
String A = "銀行流水A";
try {
ex.exchange(A);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadPool.execute(()->{
String B = "銀行流水B";
try {
String A = ex.exchange("B");
System.out.println("A錄入:"+A);
System.out.println("B錄入:"+B);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadPool.shutdown();
}
}
相關文章
- 《java併發程式設計的藝術》原子操作類Java程式設計
- Java併發程式設計藝術Java程式設計
- 《java併發程式設計的藝術》併發容器和框架Java程式設計框架
- Java併發程式設計的藝術,解讀併發程式設計的優缺點Java程式設計
- 《java併發程式設計的藝術》Executor框架Java程式設計框架
- 《java併發程式設計的藝術》併發底層實現原理Java程式設計
- Java併發程式設計的藝術(五)——中斷Java程式設計
- 《java併發程式設計的藝術》記憶體模型Java程式設計記憶體模型
- 《java併發程式設計的藝術》執行緒池Java程式設計執行緒
- 【讀書筆記】Java併發程式設計的藝術筆記Java程式設計
- java併發程式設計:Thread類的使用Java程式設計thread
- 如何評價《Java 併發程式設計藝術》這本書?Java程式設計
- 併發程式設計(二)——併發類容器ConcurrentMap程式設計
- java併發程式設計系列:java併發程式設計背景知識Java程式設計
- 併發程式設計之:JUC併發控制工具程式設計
- java 併發程式設計Java程式設計
- Java併發程式設計Java程式設計
- Java併發程式設計-鎖及併發容器Java程式設計
- java併發程式設計工具類JUC第八篇:ConcurrentHashMapJava程式設計HashMap
- java併發程式設計工具類JUC第二篇:ArrayBlockingQueueJava程式設計BloC
- Java併發程式設計---java規範與模式下的併發程式設計1.1Java程式設計模式
- Java併發程式設計 - 第十一章 Java併發程式設計實踐Java程式設計
- Java併發程式設計—ThreadLocalJava程式設計thread
- Java併發程式設計:synchronizedJava程式設計synchronized
- Java併發程式設計 -- ThreadLocalJava程式設計thread
- Java併發程式設計 -- ConditionJava程式設計
- Java併發程式設計——ThreadLocalJava程式設計thread
- java-併發程式設計Java程式設計
- Java 併發程式設計解析Java程式設計
- Java併發程式設計-CASJava程式設計
- Java併發程式設計:LockJava程式設計
- 突擊併發程式設計JUC系列-併發工具 Semaphore程式設計
- java多執行緒與併發 - 併發工具類Java執行緒
- Java併發系列—工具類:SemaphoreJava
- Java併發程式設計ForkJoin的DemoJava程式設計
- 【Java併發程式設計】一、為什麼需要學習併發程式設計?Java程式設計
- Java併發程式設計之synchronizedJava程式設計synchronized
- Java併發程式設計實踐Java程式設計