JAVA基础—JUC包(java.util.concurrent)

1. JUC - CountDownLatch 倒计时锁

/**
 * 倒计时锁
 */
public class CountDownLatchSample {
    private static int count = 0;

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(100);
        CountDownLatch countDownLatch = new CountDownLatch(10000);
        for (int i = 1; i <= 10000; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    //多个线程运行时 代码需要同步
                    synchronized (CountDownLatchSample.class){
                        try {
                            count = count + index;
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            countDownLatch.countDown();
                        }
                    }
                }
            });
        }

        //倒计时锁await()结束后才继续往后执行
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(count);
        //关闭线程池
        threadPool.shutdown();
    }

}

运行结果

50005000

2. JUC之Semaphore信号量

/**
 * Semaphore信号量经常用于限制获取某种资源的线程数量
 */
public class SemaphoreSample {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(5);//定义5个信号量
        for (int i = 1; i <= 20; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();//获取一个信号量,"占用一个跑道"
                        play();
                        semaphore.release();//执行完成后,释放这个信号量
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        //关闭线程池
        threadPool.shutdown();

    }

    public static void play() {
        try {
            System.out.println(new Date() + " " + Thread.currentThread().getName() + ":获得进入服务器资格");
            Thread.sleep(2000);
            System.out.println(new Date() + " " + Thread.currentThread().getName() + ":退出服务器");
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果

Wed Aug 08 12:08:16 CST 2018 pool-1-thread-7:退出服务器
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-10:退出服务器
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-11:获得进入服务器资格
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-14:获得进入服务器资格
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-15:获得进入服务器资格
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-18:获得进入服务器资格
Wed Aug 08 12:08:16 CST 2018 pool-1-thread-19:获得进入服务器资格
Wed Aug 08 12:08:18 CST 2018 pool-1-thread-11:退出服务器
Wed Aug 08 12:08:18 CST 2018 pool-1-thread-14:退出服务器
Wed Aug 08 12:08:18 CST 2018 pool-1-thread-19:退出服务器
Wed Aug 08 12:08:18 CST 2018 pool-1-thread-18:退出服务器
Wed Aug 08 12:08:18 CST 2018 pool-1-thread-15:退出服务器

---------------------------------------------------------------------

/**
  信号量已满时 不再执行其它线程
*/
public class SemaphoreSample {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(5);//定义5个信号量
        for (int i = 1; i <= 20; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    if (semaphore.tryAcquire()) {//尝试获取一次信号量,获取到返回true,否则返回false
                        play();
                        semaphore.release();//执行完成后,释放这个信号量
                    } else {
                        System.out.println(Thread.currentThread().getName() + ":对不起服务器已满,请稍后再试");
                    }
                }
            });
        }

        //关闭线程池
        threadPool.shutdown();

    }

    public static void play() {
        try {
            System.out.println(new Date() + " " + Thread.currentThread().getName() + ":获得进入服务器资格");
            Thread.sleep(2000);
            System.out.println(new Date() + " " + Thread.currentThread().getName() + ":退出服务器");
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果

pool-1-thread-5:对不起服务器已满,请稍后再试
pool-1-thread-6:对不起服务器已满,请稍后再试
pool-1-thread-8:对不起服务器已满,请稍后再试
pool-1-thread-9:对不起服务器已满,请稍后再试
pool-1-thread-10:对不起服务器已满,请稍后再试
pool-1-thread-18:对不起服务器已满,请稍后再试
pool-1-thread-19:对不起服务器已满,请稍后再试
pool-1-thread-13:对不起服务器已满,请稍后再试
pool-1-thread-12:对不起服务器已满,请稍后再试
pool-1-thread-17:对不起服务器已满,请稍后再试
pool-1-thread-16:对不起服务器已满,请稍后再试
pool-1-thread-20:对不起服务器已满,请稍后再试
pool-1-thread-14:对不起服务器已满,请稍后再试
pool-1-thread-15:对不起服务器已满,请稍后再试
pool-1-thread-11:对不起服务器已满,请稍后再试
Wed Aug 08 12:14:51 CST 2018 pool-1-thread-3:获得进入服务器资格
Wed Aug 08 12:14:51 CST 2018 pool-1-thread-1:获得进入服务器资格
Wed Aug 08 12:14:51 CST 2018 pool-1-thread-4:获得进入服务器资格
Wed Aug 08 12:14:51 CST 2018 pool-1-thread-7:获得进入服务器资格
Wed Aug 08 12:14:51 CST 2018 pool-1-thread-2:获得进入服务器资格
Wed Aug 08 12:14:53 CST 2018 pool-1-thread-1:退出服务器
Wed Aug 08 12:14:53 CST 2018 pool-1-thread-7:退出服务器
Wed Aug 08 12:14:53 CST 2018 pool-1-thread-4:退出服务器
Wed Aug 08 12:14:53 CST 2018 pool-1-thread-2:退出服务器
Wed Aug 08 12:14:53 CST 2018 pool-1-thread-3:退出服务器

-------------------------------------------------------------------------------------

/**
 * 信号量已满时 不再执行其它线程
 */
public class SemaphoreSample {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        Semaphore semaphore = new Semaphore(5);//定义5个信号量
        for (int i = 1; i <= 20; i++) {
            final int index = i;
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        //尝试获取一次信号量,6秒钟内获取到返回true,否则返回false
                        if (semaphore.tryAcquire(6,TimeUnit.SECONDS)) {
                            play();
                            semaphore.release();//执行完成后,释放这个信号量
                        } else {
                            System.out.println(Thread.currentThread().getName() + ":对不起服务器已满,请稍后再试");
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        //关闭线程池
        threadPool.shutdown();

    }

运行结果

Wed Aug 08 12:22:55 CST 2018 pool-1-thread-4:获得进入服务器资格
Wed Aug 08 12:22:55 CST 2018 pool-1-thread-3:获得进入服务器资格
Wed Aug 08 12:22:55 CST 2018 pool-1-thread-6:获得进入服务器资格
Wed Aug 08 12:22:55 CST 2018 pool-1-thread-2:获得进入服务器资格
Wed Aug 08 12:22:55 CST 2018 pool-1-thread-1:获得进入服务器资格
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-4:退出服务器
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-6:退出服务器
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-1:退出服务器
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-3:退出服务器
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-2:退出服务器
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-5:获得进入服务器资格
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-7:获得进入服务器资格
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-11:获得进入服务器资格
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-15:获得进入服务器资格
Wed Aug 08 12:22:57 CST 2018 pool-1-thread-10:获得进入服务器资格
Wed Aug 08 12:22:59 CST 2018 pool-1-thread-5:退出服务器
Wed Aug 08 12:22:59 CST 2018 pool-1-thread-11:退出服务器
Wed Aug 08 12:22:59 CST 2018 pool-1-thread-7:退出服务器
Wed Aug 08 12:22:59 CST 2018 pool-1-thread-10:退出服务器
Wed Aug 08 12:22:59 CST 2018 pool-1-thread-15:退出服务器
Wed Aug 08 12:23:00 CST 2018 pool-1-thread-8:获得进入服务器资格
Wed Aug 08 12:23:00 CST 2018 pool-1-thread-12:获得进入服务器资格
Wed Aug 08 12:23:00 CST 2018 pool-1-thread-14:获得进入服务器资格
Wed Aug 08 12:23:00 CST 2018 pool-1-thread-13:获得进入服务器资格
Wed Aug 08 12:23:00 CST 2018 pool-1-thread-9:获得进入服务器资格
pool-1-thread-17:对不起服务器已满,请稍后再试
pool-1-thread-20:对不起服务器已满,请稍后再试
pool-1-thread-19:对不起服务器已满,请稍后再试
pool-1-thread-18:对不起服务器已满,请稍后再试
pool-1-thread-16:对不起服务器已满,请稍后再试
Wed Aug 08 12:23:02 CST 2018 pool-1-thread-8:退出服务器
Wed Aug 08 12:23:02 CST 2018 pool-1-thread-12:退出服务器
Wed Aug 08 12:23:02 CST 2018 pool-1-thread-14:退出服务器
Wed Aug 08 12:23:02 CST 2018 pool-1-thread-13:退出服务器
Wed Aug 08 12:23:02 CST 2018 pool-1-thread-9:退出服务器

3. JUC之CyclicBarrier循环屏障

/**
 * CyclicBarrier循环屏障
 * 是一个同步工具类,它允许一组线程互相等待,知道到达某个公共屏障点
 * 与CountDawnLatch不同的是该barrier在释放等待线程后可以重用
 */
public class CyclicBarrierSample {
    //定义屏障点 5个线程
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newCachedThreadPool();
        for (int i = 1; i <= 10; i++) {
            final int index = i;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    go();
                }
            });
        }

        //关闭线程池
        threadPool.shutdown();
    }

    private static void go() {
        System.out.println(Thread.currentThread().getName() + " : 准备就绪");
        try {
            cyclicBarrier.await();//设置屏障点,当累计5个线程都准备好后,才运行后面的代码
            System.out.println(Thread.currentThread().getName() + " : 开始运行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

运行结果

pool-1-thread-1 : 准备就绪
pool-1-thread-2 : 准备就绪
pool-1-thread-3 : 准备就绪
pool-1-thread-4 : 准备就绪
pool-1-thread-5 : 准备就绪
pool-1-thread-5 : 开始运行
pool-1-thread-1 : 开始运行
pool-1-thread-3 : 开始运行
pool-1-thread-2 : 开始运行
pool-1-thread-4 : 开始运行
pool-1-thread-4 : 准备就绪
pool-1-thread-2 : 准备就绪
pool-1-thread-3 : 准备就绪
pool-1-thread-1 : 准备就绪
pool-1-thread-5 : 准备就绪
pool-1-thread-5 : 开始运行
pool-1-thread-4 : 开始运行
pool-1-thread-2 : 开始运行
pool-1-thread-1 : 开始运行
pool-1-thread-3 : 开始运行

4. JUC之Conditon线程等待与唤醒

/**
 * Codintion线程的等待与唤醒
 * 需要配合ReentrantLock 重入锁使用
 */
public abstract class ConditonSample {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Condition condition3 = lock.newCondition();

        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    condition1.await();
                    Thread.sleep(1000);
                    System.out.println("粒粒皆辛苦");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {//重入锁需要手动解锁
                    lock.unlock();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    condition2.await();
                    Thread.sleep(1000);
                    System.out.println("谁知盘中餐");
                    condition1.signal();//唤醒c1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {//重入锁需要手动解锁
                    lock.unlock();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    condition3.await();
                    Thread.sleep(1000);
                    System.out.println("汗滴禾下土");
                    condition2.signal();//唤醒c2
                }catch (Exception e){
                    e.printStackTrace();
                }finally {//重入锁需要手动解锁
                    lock.unlock();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                lock.lock();
                try {
                    Thread.sleep(1000);
                    System.out.println("锄禾日当午");
                    condition3.signal(); //唤醒c3
                }catch (Exception e){
                    e.printStackTrace();
                }finally {//重入锁需要手动解锁
                    lock.unlock();
                }
            }
        }).start();

    }
}

运行结果

锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦

5. JUC之Callable_Future

JAVA基础—JUC包(java.util.concurrent)_第1张图片
Callable&Future
public class Callable_Future_Sample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //打印1000以内的质数
        for (int i = 2; i <= 1000; i++) {
            Computor computor = new Computor();
            computor.setNum(i);
            //将computor对象提交给线程池,如果有空闲线程立即执行里面的call方法
            //Future是对用于计算的线程进行监听,应为计算时在其它线程中执行的,所以这个返回的结果时异步的
            Future submitResult = executorService.submit(computor);
            try {
                //用于获取返回值,如果线程池内部的call方法没有执行完成,则进入等待状态,知道计算完成
                Boolean r = submitResult.get();
                if (r == true) {
                    System.out.println(computor.getNum());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        //关闭线程池
        executorService.shutdown();
    }
}

class Computor implements Callable {
    private Integer num;

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num = num;
    }

    @Override
    public Boolean call() throws Exception {
        boolean isprime = true;
        for (int i = 2; i < num; i++) {
            if (num % i == 0) {
                isprime = false;
                break;
            }
        }
        return isprime;
    }
}

运行结果

2
3
5
7
11
13
17
19

你可能感兴趣的:(JAVA基础—JUC包(java.util.concurrent))