zoukankan      html  css  js  c++  java
  • 面试刷题19:并发工具包有哪些工具?

    image.png


    java.util.concurrent包提供了大量的并发工具。




    大家好,我是李福春,今天的题目是:


    java提供的并发工具有哪些?


    答:java.util.concurrent工具包中提供的工具分4大类。


    一, 同步工具,CountDownLatch, CyclicBarrier , Semaphore ;
    二, 并发安全容器, ConcurrentHashMap,ConcurrentSkipListMap,
    CopyOnWriteArrayList,CopyOnWriteArraySet;
    三,并发安全队列,主要用在线程池上,ArrayBlockingQueue,SynchronousQueue,PriorityBlockingQueue;
    四,并发线程池executor框架;




    同步工具

    semaphore


    信号量,设置并发访问的线程数量。


    一般要结对使用: try{s.acquire();}finally{s.release()}

    package org.example.mianshi.synctool;
    
    import java.util.concurrent.Semaphore;
    
    /**
     * 创建日期:  2020/3/30 14:24
     * 描述:     信号量应用
     *
     * @author lifuchun
     */
    
    public class SemaphoreApp {
    
    
        public static void main(String[] args) {
    
            Semaphore semaphore = new Semaphore(0);
    
            for (int i = 1; i <= 10; i++) {
                new MyThread(semaphore).start();
            }
    
            System.out.println("go ```");
            semaphore.release(5);
    
    
        }
    
        public static class MyThread extends Thread {
    
            private Semaphore semaphore;
    
            public MyThread(Semaphore semaphore) {
                this.semaphore = semaphore;
            }
    
            @Override
            public void run() {
    
                try {
    
                    semaphore.acquire();
    
                    System.out.println(System.currentTimeMillis() + " :" + Thread.currentThread().getName() + " -execute ```");
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
    
    
            }
        }
    
    
    }
    

    CountDownLatch


    设置线程等待某些操作完成;


    其它线程完成了,调用 c.countDown()


    当c的value=0,即执行 其它线程在 await()方法后面逻辑。


    package org.example.mianshi.synctool;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.stream.IntStream;
    
    /**
     * 创建日期:  2020/3/30 14:38
     * 描述:     countDownLatch的例子
     * @author lifuchun
     */
    
    public class CountDownLatchApp {
    
        public static void main(String[] args) {
    
            CountDownLatch countDownLatch = new CountDownLatch(5);
    
            new Thread(() -> {
    
                try {
                    countDownLatch.await();
    
                    System.out.println("后置任务");
    
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
    
    
            IntStream.rangeClosed(1, 10)
                    .forEach(i -> new MyThread(countDownLatch).start());
    
    
        }
    
        public static class MyThread extends Thread {
    
            private CountDownLatch countDownLatch;
    
            public MyThread(CountDownLatch countDownLatch) {
                this.countDownLatch = countDownLatch;
            }
    
            @Override
            public void run() {
    
                countDownLatch.countDown();
    
                System.out.println("前置任务");
    
    
            }
        }
    
    }
    

    CyclicBarrier


    允许多个线程同时到达某个屏障。 设置并发执行的线程数量。


    一般调用await()方法,当数量达到预设的数量N,则统一执行await()方法后面的逻辑,会自动重置。


    package org.example.mianshi.synctool;
    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.stream.IntStream;
    
    /**
     * 创建日期:  2020/3/30 14:49
     * 描述:     cyclicBarrier的应用
     *
     * @author lifuchun
     */
    
    public class CyclicBarrierApp {
    
        public static void main(String[] args) {
    
            CyclicBarrier cyclicBarrier = new CyclicBarrier(3, CyclicBarrierApp::run);
    
            IntStream.rangeClosed(1, 30)
                    .forEach(i -> new MyThread(cyclicBarrier).start());
    
        }
    
        private static void run() {
            System.out.println("reset , start again !");
        }
    
        public static class MyThread extends Thread {
    
            private CyclicBarrier cyclicBarrier;
    
            public MyThread(CyclicBarrier cyclicBarrier) {
                this.cyclicBarrier = cyclicBarrier;
            }
    
            @Override
            public void run() {
    
                try {
                    cyclicBarrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    e.printStackTrace();
                }
    
                System.out.println("do my work!");
    
            }
        }
    
    }
    

    image.png


    同步安全容器


    类层级如下图:

    image.png







    场景选择:


    1, 如果注重的是并发放入和获取的速度,使用ConcurrentHashMap ; 


    2, 如果注重顺序,并且频繁并发修改大量的数据,使用ConcurrentSkipListMap




    CopyOnWrite*防御复制:


    add,set,remote操作都会copy原数组,修改完成之后替换原来的数组,代价比较大,适合读多写少的场景;






    小结


    本篇回答了java.util.concurrent工具包中的分类的工具,主要介绍了3个同步工具,Semaphore , CountDownLatch, CyclicBarrier  ;


    然后画出了并发安全容器的类层级图,分析了不同的场景下如何选择合适的并发安全容器。





    image.png

    原创不易,转载请注明出处。

  • 相关阅读:
    洛谷P1022计算器的改良(字符串+各种细节坑点考虑)
    hdu5974Math Problem(数学,思维,公式,取巧猜)
    牛客练习赛26A平面(数学公式)
    洛谷P1217回文质数(特判筛选,取巧判断顺序)
    尺取法
    51nod1006最长公共子序列(lcs输出路径)
    51nod1175区间第k大(小)数(主席树模板)
    51nod1174区间中最大的数(rmq模板或线段树 && 线段树标准模板)
    51nod1094和为k连续区间(前缀和+map判断优化)
    矩阵快速幂求递推数列
  • 原文地址:https://www.cnblogs.com/snidget/p/12598857.html
Copyright © 2011-2022 走看看