美文网首页java基础
JAVA基础—JUC包(java.util.concurrent

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

作者: 东方舵手 | 来源:发表于2018-08-08 00:09 被阅读6次

    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

    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<Boolean> 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<Boolean> {
        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

        本文链接:https://www.haomeiwen.com/subject/xegzvftx.html