java 1.5 并发流程控制CountDownLatch,CyclicBarrier,Semaphore

来源:互联网 发布:网络诈骗小金额 编辑:程序博客网 时间:2024/06/15 18:08

一:CountDownLatch

CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。

用法1:有一个任务A要等其他几个任务执行完后执行,任务A中调用await()方法(任务A线程就阻塞等待了),其他几个任务线程执行完调用countDown()方法,当countdown为0时,任务A线程就唤醒继续执行了。

用法2:也可以反过来,比如有N个任务需要等某一条件后才能继续执行,那就在N个任务中调用await()方法,条件达成后调用countDown()方法,那N个任务就能继续执行了 。

实例代码:

public static void main(String a[]){
        int N =4;
        final CountDownLatch countDownLatch = new CountDownLatch(1);
        for(int i = 0;i<N;i++){
            new MyThread("线程"+i,countDownLatch).start();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                long waitTime = new Random().nextInt(3000);
                try {
                    Thread.sleep(waitTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print("main waitTime:"+waitTime);
                countDownLatch.countDown();
            }
        }).start();
    }


    static class MyThread extends Thread implements Runnable {
        CountDownLatch countDownLatch;
        MyThread(String name,CountDownLatch countDownLatch){
            this.countDownLatch=countDownLatch;
            this.setName(name);
        }

        @Override
        public void run() {
            System.out.print(getName()+" wait");
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(getName()+" goon");
        }
    }


二:CyclicBarrier

用法一:比如有N个任务线程,new 一个CyclicBarrier对象,传入参数N,每个线程执行到一定代码调用await()方法,线程就挂起,当全部线程都调用了await()方法后,所有线程就唤醒继续执行了。

实例代码:

public static void main(String a[]){
        int N =4;
        CyclicBarrier cyclicBarrier = new CyclicBarrier(N);
        for(int i = 0;i<N;i++){
            new MyThread("线程"+i,cyclicBarrier).start();
        }
    }

    static class MyThread extends Thread implements Runnable {
        CyclicBarrier cyclicBarrier;
        MyThread(String name,CyclicBarrier cyclicBarrier){
            this.cyclicBarrier=cyclicBarrier;
            this.setName(name);
        }

        @Override
        public void run() {
            System.out.print(getName()+" wait");
            long waitTime = new Random().nextInt(3000);
                try {
                    Thread.sleep(waitTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(getName()+"waitTime:" + waitTime);
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.print(getName()+" goon");
        }
    }

用法二:创建对象时可以传入一个runnable对象,唤醒时先执行runnalble,再继续执行各自线程任务。


三:Semaphore

Semaphore可以控同时访问的线程个数。

用法:比如有个方法同时只能两个线程同时访问,那N个任务线程,执行前先调用acquire() 获取一个许可,获取到了就能继续,没获取到就等待,当然执行完记得调用release() 释放一个许可,让其他线程能进去。


0 0
原创粉丝点击