Java并发包中提供了很多有用的工具类来帮助开发者进行并发编程,今天我就来说说CountDownLatch,CyclicBarrier以及Semaphore这三个的用法和使用场景。
1.CountDownLatch使用场景和用法
CountDownLatch一般是用于某个线程等待其他线程执行完之后,它才能执行。例如一家人在等待爸爸妈妈回家,才能进行晚宴,示例代码如下:
public class CountDownLatchTest {
public static void main(String[] args) throws Exception {
final CountDownLatch cdl = new CountDownLatch(2);
new Thread(){
public void run() {
try {
System.out.println("等待老爸回家...");
Thread.sleep(5000);
cdl.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
new Thread(){
public void run() {
try {
System.out.println("等待老妈回家...");
Thread.sleep(5000);
cdl.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
cdl.await();
System.out.println("老爸老妈回来了...");
System.out.println("晚宴开始了...");
}
}
CyclicBarrier一般是一组线程等待至某个状态,然后这一组线程才能同时执行(感觉跟CountDownLatch有点类似啊,不过仔细想想还是有差别的,感觉容易混淆)。
代码示例如下:
public class CyclicBarrierTest {
public static void main(String[] args) {
int count = 3;
CyclicBarrier cb = new CyclicBarrier(count, new Runnable() {
@Override
public void run() {
//此处所有线程都调用了await方法之后,会走到这里
System.out.println("所有线程操作完成之后都调用了await方法");
}
});
for(int i=0;i<count;i++){
new WriteLogHandler(cb).start();
}
}
static class WriteLogHandler extends Thread{
private CyclicBarrier cb = null;
public WriteLogHandler(CyclicBarrier cb) {
this.cb = cb;
}
@Override
public void run() {
try {
System.out.println("线程:" + Thread.currentThread().getName() + "开始写日志");
Thread.sleep(2000);
System.out.println("线程:" + Thread.currentThread().getName() + "写日志结束,等待其他线程");
cb.await();
System.out.println("所有线程写日志数据结束,继续其他操作");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3.Semaphore(信号量)使用场景和用法
Semaphore类似锁的用法,用于控制对某资源的访问权限,示例代码如下:
public class SemaphoreTest {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(5);
for(int i=0;i<10;i++){
final int num = i;
executor.execute(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire();
System.out.println("正在执行任务" + num);
Thread.sleep((long)Math.random() * 1000);
System.out.println("任务" + num + "执行结束");
semaphore.release();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
executor.shutdown();
}
}
以上就是这三个并发工具类的使用场景和示例,欢迎大家一起交流。