您的位置:首页 > 其它

concurrent包下的CyclicBarrier和CountDownLatch以及Semaphore

2017-12-23 20:13 393 查看
CyclicBarrier:

它可以让多个线程中执行得快的线程在某一个时间点阻塞,然后等待最后一个线程执行到该点的时候,同时往下执行。

示例代码:

public class CyclicBarrierDemo {

static class Runner implements Runnable {
private CyclicBarrier barrier;
private String name;

public Runner(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}

@Override
public void run() {
try {
Thread.sleep(1000 * (new Random()).nextInt(5));
System.out.println(name + "开始阻塞等待");
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(name + "阻塞完毕,全体执行");
}
}

public static void main(String[] args) throws IOException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(3);
ExecutorService executor = Executors.newFixedThreadPool(3);

executor.submit(new Thread(new Runner(barrier, "t1")));
executor.submit(new Thread(new Runner(barrier, "t2")));
executor.submit(new Thread(new Runner(barrier, "t3")));

executor.shutdown();
}
}


CountDownLatch:

它和Thread的join方法很类似,但是join方法只能在上游线程都执行完成后面的线程才能执行,而CountDownLatch可以在上游线程执行的逻辑中自己控制,比如执行到某个逻辑的时候就可以让下面的线程执行,上游线程可以继续执行其他逻辑。

示例代码:

public class CountDownLatchDemo {

public static void main(String[] args) {

final CountDownLatch countDown = new CountDownLatch(2);

new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t1开始执行,并调用await");
countDown.await();
System.out.println("t1执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t2开始执行");
Thread.sleep(2000);
System.out.println("t2执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDown.countDown();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("t3开始执行");
Thread.sleep(5000);
System.out.println("t3执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
countDown.countDown();
}
}
}).start();

}
}


Semaphore

它可以用于控制线程的并行个数。

示例代码:

public class SemaphoreDemo {
public static void main(String[] args) {
// 只能5个线程同时访问
final Semaphore semp = new Semaphore(5);
// 模拟20个客户端访问
for (int index = 0; index < 20; index++) {
final int num = index;
new Thread() {
public void run() {
try {
semp.acquire();
System.out.println("当前进来的线程: " + num);
Thread.sleep((long) (Math.random() * 10000));
semp.release();
} catch (InterruptedException e) {
}
}
}.start();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: