• JAVA并发编程学习笔记------基础构建模块


    一、并发容器:
    ConcurrentHashMap:
    1、分段锁机制: 任意数量的读取线程可以并发的访问map,执行读取操作的线程和执行写入操作的线程可以并发的访问Map,并且一定数量的写入线程可以并发的修改Map。
    2、无需再迭代过程中对容器加锁;
    3、ConcurrentHashMap无法实现对Map加锁已提供独占访问,在HashMap及SynchrogazedMap中,获得Map的锁能防止其他线程访问这个Map;
    4、大多数情况下,用ConcurrentHashMap代替同步Map能进一步提高代码的可伸缩性,只有当应用程序需要加锁Map以进行独占访问时,才应该放弃使用ConcurrentHashMap。


    CopyOnWriteArrayList:
    1、用于代替同步List,迭代期间不需要对容器进行加锁或复制;
    2、 容器的线程安全性在于: 只要正确的发布一个事实不可变的对象,那么在访问该对象时就不需要进一步的同步,在每次修改时,都会创建并重新发布一个新的容器副本,从而实现可变性。
    3、仅当迭代操作远远多于修改操作时,才应该使用“写入时复制”容器。

    二、同步工具类:
    1. 闭锁:
    (1)延迟线程的进度直到其到达终止状态,可用来确保某些活动直到其他活动都完成后才继续执行;
    (2)实现:CountDownLatch

    public class TestHarness {
        public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
            final CountDownLatch startGate = new CountDownLatch(1);
            final CountDownLatch endGate = new CountDownLatch(nThreads);
            for(int i=0;i<nThreads;i++){
                Thread t = new Thread(){
                    public void run(){
                        try{
                            startGate.await();
                            try {
                                task.run();
                            }finally {
                                endGate.countDown();
                            }
                        }catch (InterruptedException ignored){
    
                        }
                    }
                };
                t.start();
            }
            long start = System.nanoTime();
            startGate.countDown();
            endGate.await();
            long end = System.nanoTime();
            return end-start;
        }
    }
    

      

    2、栅栏(Barrier)
    (1)栅栏类似于闭锁,它能阻塞一组线程直到某个事件发生,它与闭锁的关键区别在于:所有线程必须同时到达栅栏,才能继续执行。闭锁用于等待事件,而栅栏用于等待线程。闭锁一旦打开将不会再关闭,栅栏打开后还可以重置以供下次使用。

    (2)实现方式: CyclicBarrier(摘自http://www.itzhai.com/the-introduction-and-use-of-cyclicbarrier.html)

    public class CyclicBarrierTest {
        public static void main(String[] args) throws IOException, InterruptedException {
            CyclicBarrier barrier = new CyclicBarrier(3);
    
            ExecutorService executor = Executors.newFixedThreadPool(3);
            executor.submit(new Thread(new Runner(barrier, "1号选手")));
            executor.submit(new Thread(new Runner(barrier, "2号选手")));
            executor.submit(new Thread(new Runner(barrier, "3号选手")));
    
            executor.shutdown();
        }
    
        static class Runner implements Runnable{
            private CyclicBarrier barrier;
    
            private String name;
    
            public Runner(CyclicBarrier barrier, String name) {
                super();
                this.barrier = barrier;
                this.name = name;
            }
    
            @Override
            public void run() {
                try {
                    Thread.sleep(1000 * (new Random()).nextInt(8));
                    System.out.println(name + " 准备好了...");
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println(name + " 起跑!");
            }
        }
    }
    

      

  • 相关阅读:
    无法加载 DLL“librdkafka”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
    C#编码规范
    requests(五)
    python-requests(四):调用上传文件的接口的解决方案
    静态代码扫描工具
    推荐一款 python 管理工具:anaconda
    selenium 网页自动化-在访问一个网页时弹出的浏览器窗口,我该如何处理?
    静态代码扫描工具
    静态代码扫描工具
    静态代码扫描工具
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/6075214.html
Copyright © 2020-2023  润新知