有些时候有这样的情况,需要多个线程同时开始执行任务。为了实现这样的需求,我大概想到了以下两种方式。
第一种方式是采用CyclicBarrier类来实现,让多个线程相互等待,直到达到一个屏障点,并且 CyclicBarrier是可重用的。
第二种方案是使用CountDownLatch来实现,当计数器为0的时候,所有等待的线程都被唤醒,开始执行他们的任务。

CyclicBarrier的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {

public static void main(String[] args) {
CyclicBarrierTest cyclicBarrierTest=new CyclicBarrierTest();
cyclicBarrierTest.runThread();
}
CyclicBarrier cyclicBarrier=new CyclicBarrier(10);

/**
* 创建一个线程
* @return
*/
private Thread createThread(int i){
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
cyclicBarrier.await();
System.out.println("thread"+Thread.currentThread().getName()+"准备完毕"+System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}catch (BrokenBarrierException e){
e.printStackTrace();
}

}
});
thread.setName("thread-"+i);
return thread;
}

public void runThread(){
ExecutorService executorService= Executors.newFixedThreadPool(10);

try {
for(int i=0;i<10;i++){
Thread.sleep(100);
executorService.submit(createThread(i));
}
}catch (InterruptedException e){
e.printStackTrace();
}

}
}

CountDownLatch 的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.concurrent.*;


public class CountDownLatchTest {

public static void main(String[] args) {
CountDownLatchTest countDownLatchTest=new CountDownLatchTest();
countDownLatchTest.runThread();
}
CountDownLatch countDownLatch=new CountDownLatch(10);

/**
* 创建一个线程
* @return
*/
private Thread createThread(int i){
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
try {
countDownLatch.await();
System.out.println("thread"+Thread.currentThread().getName()+"准备完毕"+System.currentTimeMillis());
}catch (InterruptedException e){
e.printStackTrace();
}

}
});
thread.setName("thread-"+i);
return thread;
}

public void runThread(){
ExecutorService executorService= Executors.newFixedThreadPool(10);

try {
for(int i=0;i<10;i++){
Thread.sleep(100);
executorService.submit(createThread(i));
//待等待的线程数减去一
countDownLatch.countDown();
}
}catch (InterruptedException e){
e.printStackTrace();
}

}
}

输出结果

两种方案的输出类似,10个线程同时开始工作

1
2
3
4
5
6
7
8
9
10
threadpool-1-thread-2准备完毕1569143420252
threadpool-1-thread-6准备完毕1569143420252
threadpool-1-thread-8准备完毕1569143420252
threadpool-1-thread-9准备完毕1569143420252
threadpool-1-thread-7准备完毕1569143420252
threadpool-1-thread-5准备完毕1569143420252
threadpool-1-thread-3准备完毕1569143420252
threadpool-1-thread-4准备完毕1569143420252
threadpool-1-thread-1准备完毕1569143420252
threadpool-1-thread-10准备完毕1569143420252