利用countDownLatch將非同步多執行緒結果同步返回
阿新 • • 發佈:2019-02-16
最近專案在執行過程中,有多個 獨立模組 非同步執行,將執行結果統一處理後返回,程式碼可以順序呼叫各個模組執行,然後統一處理,但是效率過低,考慮採用多執行緒非同步處理,但非同步執行提交任務後就順序執行其他程式碼了,無法統一獲取各模組處理結果。採用countDownLatch可以等待所有非同步執行緒執行完成再統一處理。
- countDownLatch jdk裡描述
A synchronization aid that allows one or more threads to wait until
a set of operations being performed in other threads completes.
一個允許等待一個或多個其它執行緒執行完成的同步助手
使用場景:
1.等待一個或多個執行緒完成再執行其它操作
2.等待一個執行緒執行多次再執行其它操作
- countDownLatch實現原理
private final Sync sync;
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
初始化時將任務個數傳遞給同步控制器Sync,每次呼叫countDown方法,開始執行非同步任務,Sync釋放一個資源
public void countDown() {
sync.releaseShared(1 );
}
呼叫await,await方法判斷Sycn的狀態,如果Sync狀態顯示未執行完成,則繼續分配資源執行。
當countDown為0時,統一返回非同步結果。
- 程式碼示例
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class MultiJobExecutors {
private CountDownLatch countDownLatch;
private List<Task> tasks;
private static ExecutorService executor = null;
public MultiJobExecutors(List<Task> tasks) {
countDownLatch = new CountDownLatch(tasks.size());
executor = Executors.newFixedThreadPool(tasks.size());
this.tasks = tasks;
}
public void execute() {
if (tasks == null|| tasks.isEmpty()) {
return;
}
for (int i=0;i< tasks.size();i++) {
executor.submit(new Job(countDownLatch,tasks.get(i)));
System.out.println("xx"+i);
}
try {
//等待所有執行緒結束
countDownLatch.await(15, TimeUnit.SECONDS);
//執行其他操作
System.out.println("it's over");
//關閉執行緒池
executor.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class Job implements Callable<Object>{
private CountDownLatch latch;
private Task task;
public Job(CountDownLatch latch, Task task) {
this.latch = latch;
this.task = task;
}
@Override
public Object call() throws Exception {
System.out.println(System.currentTimeMillis());
//執行執行緒
task.execute();
//countDown自減
latch.countDown();
return null;
}
}
private static class Task{
private String str;
public Task(String str) {
this.str = str;
}
public void execute(){
System.out.println(str);
}
}
public static void main(String[] args) {
Task task = new Task("I");
Task task1 = new Task("love");
Task task2 = new Task("you");
Task task3 = new Task(",");
Task task4 = new Task("its");
Task task5 = new Task("not");
Task task6 = new Task("true");
List<Task> tasks = new ArrayList<Task>();
tasks.add(task);
tasks.add(task1);
tasks.add(task2);
tasks.add(task3);
tasks.add(task4);
tasks.add(task5);
tasks.add(task6);
MultiJobExecutors multiJobExecutors = new MultiJobExecutors(tasks);
multiJobExecutors.execute();
}
}
- 執行結果
xx0
1472706027197
I
xx1
1472706027197
love
xx2
1472706027197
you
xx3
1472706027197
,
xx4
1472706027197
its
xx5
1472706027198
not
xx6
1472706027198
true
it's over