如果是一个线程等待一个线程,则可以通过await()和notify()来实现;如果是一个线程等待多个线程,则就可以使用CountDownLatch和CyclicBarrier来实现比较好的控制。
CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。 CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。 这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。
CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.
而CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
CountDownLatch示例
package com.wlyuan.CountDownLatch;
/**
* Created by wlyuan on 17-3-12.
*/
import java.util.concurrent.*;
import java.util.*;
class TaskPortion implements Runnable {
private static int counter =
0;
private final int id = counter++;
private static Random rand =
new Random(
47);
private final CountDownLatch latch;
TaskPortion(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
doWork();
latch.countDown();
}
catch(InterruptedException ex) {
}
}
public void doWork()
throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(rand.nextInt(
2000));
System.out.println(
this +
"completed");
}
public String
toString() {
return String.format(
"%1$-3d ", id);
}
}
class WaitingTask implements Runnable {
private static int counter =
0;
private final int id = counter++;
private final CountDownLatch latch;
WaitingTask(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
System.out.println(
"Latch barrier passed for " +
this);
}
catch(InterruptedException ex) {
System.out.println(
this +
" interrupted");
}
}
public String
toString() {
return String.format(
"WaitingTask %1$-3d ", id);
}
}
public class CountDownLatchDemo {
static final int SIZE =
100;
public static void main(String[] args)
throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
CountDownLatch latch =
new CountDownLatch(SIZE);
for(
int i =
0; i <
10; i++)
exec.execute(
new WaitingTask(latch));
for(
int i =
0; i < SIZE; i++)
exec.execute(
new TaskPortion(latch));
System.out.println(
"Launched all tasks");
exec.shutdown();
}
}
CyclicBarrier示例
package com.wlyuan.CyclicBarrier;
/**
* Created by wlyuan on 17-3-12.
*/
import java.util.concurrent.*;
import java.util.*;
class Horse implements Runnable {
private static int counter =
0;
private final int id = counter++;
private int strides =
0;
private static Random rand =
new Random(
47);
private static CyclicBarrier barrier;
public Horse(CyclicBarrier b) { barrier = b; }
public synchronized int getStrides() {
return strides; }
public void run() {
try {
while(!Thread.interrupted()) {
synchronized(
this) {
strides += rand.nextInt(
3);
}
barrier.await();
}
}
catch(InterruptedException e) {
}
catch(BrokenBarrierException e) {
throw new RuntimeException(e);
}
}
public String
toString() {
return "Horse " + id +
" "; }
public String
tracks() {
StringBuilder s =
new StringBuilder();
for(
int i =
0; i < getStrides(); i++)
s.append(
"*");
s.append(id);
return s.toString();
}
}
public class HorseRace {
static final int FINISH_LINE =
75;
private List<Horse> horses =
new ArrayList<Horse>();
private ExecutorService exec =
Executors.newCachedThreadPool();
private CyclicBarrier barrier;
public HorseRace(
int nHorses,
final int pause) {
barrier =
new CyclicBarrier(nHorses,
new Runnable() {
public void run() {
StringBuilder s =
new StringBuilder();
for(
int i =
0; i < FINISH_LINE; i++)
s.append(
"=");
System.out.println(s);
for(Horse horse : horses)
System.out.println(horse.tracks());
for(Horse horse : horses)
if(horse.getStrides() >= FINISH_LINE) {
System.out.println(horse +
"won!");
exec.shutdownNow();
return;
}
try {
TimeUnit.MILLISECONDS.sleep(pause);
}
catch(InterruptedException e) {
System.out.println(
"barrier-action sleep interrupted");
}
}
});
for(
int i =
0; i < nHorses; i++) {
Horse horse =
new Horse(barrier);
horses.add(horse);
exec.execute(horse);
}
}
public static void main(String[] args) {
int nHorses =
7;
int pause =
200;
if(args.length >
0) {
int n =
new Integer(args[
0]);
nHorses = n >
0 ? n : nHorses;
}
if(args.length >
1) {
int p =
new Integer(args[
1]);
pause = p > -
1 ? p : pause;
}
new HorseRace(nHorses, pause);
}
}
运行结果
*******************************************************************0 ************************************************************************1 ********************************************************2 ****************************************************************************3 ************************************************************************4 ***************************************************************************5 **************************************************************6 Horse 3 won!
转载请注明原文地址: https://ju.6miu.com/read-35076.html