多线程学习笔记之十四——CountDownLatch、 CyclicBarrie、Semaphore的使用

CountDownLatch

CountDownLatch的构造器:

public CountDownLatch(int count) {
        if (count < 0) throw new IllegalArgumentException("count < 0");
        this.sync = new Sync(count);
    }

count参数可以通俗的理解为countDown()方法调用的次数,当count和调用次数相同时,await()方法的线程才能继续执行。
注意:countDown()不一定是另一个线程调用。
CountDownLatch的示例:

package day3;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class CountDownLatchTest {
    private CountDownLatch c = new CountDownLatch(2);

    public static void main(String[] args) throws InterruptedException {
        CountDownLatchTest test = new CountDownLatchTest();
        ExecutorService executor = Executors.newFixedThreadPool(2);
        sumEven sumEven = test.new sumEven(1,100);
        sumOdd sumOdd = test.new sumOdd(1,100);
        executor.submit(sumEven);
        executor.submit(sumOdd);
        long start = System.currentTimeMillis();
        System.out.println("等待结果");
        test.c.await();
        System.out.println("等待时间:"+(System.currentTimeMillis() - start));
        System.out.println("偶数和:"+sumEven.getSumEven());
        System.out.println("奇数和:"+sumOdd.getSumOdd());
        executor.shutdown();
    }
    class sumEven implements Runnable{
        private int start;
        private int end;
        private int sumEven;

        public int getSumEven() {
            return sumEven;
        }
        public void setSumEven(int sumEven) {
            this.sumEven = sumEven;
        }
        public sumEven(int start,int end) {
            this.start = start;
            this.end = end;
        }
        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            sumEven = sumEvenM(start,end);
            c.countDown();
        }
        public int sumEvenM(int start,int end) {
            int sum = 0;
            for(int i = start;i<=end;i++) {
                if(i%2==0) {
                    sum = sum +i;
                }
            }
            return sum;
        }
    }
    class sumOdd implements Runnable{
        private int start;
        private int end;
        private int sumOdd;

        public int getSumOdd() {
            return sumOdd;
        }
        public void setSumOdd(int sumOdd) {
            this.sumOdd = sumOdd;
        }
        public sumOdd(int start,int end) {
            this.start = start;
            this.end = end;
        }
        @Override
        public void run() {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            sumOdd = sumOddM(start,end);
            c.countDown();
        }
        public int sumOddM(int start,int end) {
            int sum = 0;
            for(int i = start;i<=end;i++) {
                if(i%2==1) {
                    sum = sum +i;
                }
            }
            return sum;
        }
    }
}

解释:此示例开启了俩个线程,分别用来算奇数和与偶数和,等待算完后打印出来。
console输出:

等待结果
等待时间:2001
偶数和:2550
奇数和:2500

应用场景:适用于最后需要统计结果的程序,但本人感觉这种功能可以直接用fork/join框架来处理

CyclicBarrier

感觉跟CountDownLatch差不错

Semaphore

控制线程的并发数,示例如下:

package day3;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class SemaphoreTest {
    private static final int THREAD_COUNT = 30;
    private static ExecutorService threadPool = Executors.newFixedThreadPool(THREAD_COUNT);
    private static Semaphore s = new Semaphore(10);
    private static AtomicInteger j = new AtomicInteger(0);

    public static void main(String[] args) {
        for (int i = 0; i < THREAD_COUNT; i++) {
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        s.acquire();
                        System.out.println("save data"+(j.incrementAndGet()));
                        TimeUnit.SECONDS.sleep(10);
                        s.release();
                    } catch (InterruptedException e) {
                    }
                }
            });
        }
        threadPool.shutdown();
    }
}

执行结果是每十个线程并发执行。

猜你喜欢

转载自blog.csdn.net/shidebin/article/details/82686627