Java中CountDownLatch,CyclicBarrier以及Semaphore的使用场景

来源:互联网 发布:java mkdir 只读 编辑:程序博客网 时间:2024/06/06 16:39

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("晚宴开始了...");    }}


2.CyclicBarrier(栅栏)使用场景和用法
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();    }}

以上就是这三个并发工具类的使用场景和示例,欢迎大家一起交流。

0 0