zoukankan      html  css  js  c++  java
  • AQS理解

    ReentrantLock内部包含了一个AQS对象,也就是AbstractQueuedSynchronizer类型的对象。这个AQS对象就是ReentrantLock可以实现加锁和释放锁的关键性的核心组件。

     

     

    线程A,B尝试进行加锁的过程:

     

     

    /**
     * @Author:daboluo
     * @Date: 2019/9/29 8:58
     * @Version 1.0
     *
     *
     * ReentrantCountExample对count进行相加
     */
    public class ReentrantCountExample {
    
    
        private static int clientTotal = 5000;
    
        private static int threadTotal = 200;
        
        private static int count = 0;
    
        private static ReentrantLock reentrantLock = new ReentrantLock();
    
    
        public static void main(String[] args) throws Exception{
            ExecutorService exec = Executors.newCachedThreadPool();
            final Semaphore semaphore = new Semaphore(threadTotal);
            for (int i = 0; i < clientTotal; i++) {
                exec.execute(()->{
                    try {
                        semaphore.acquire();
                        add();
                        semaphore.release();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                });
            }
            Thread.sleep(5);
            exec.shutdown();
            System.out.println("count = " + count);
    
        }
    
    
        /**
         *
         * synchronized : 不可中断的,适合竞争不激烈的,可见性
         * lock: 可中断锁,多样化同步,竞争激烈时能维持常态
         * atomic:竞争激烈时能维持常态,比lock的性能更佳,能同步一个值
         *
         *
         */
        private  static void add(){
            reentrantLock.lock();
            count++;
            reentrantLock.unlock();
        }
    
    }

    结果:
    count = 5000

     

     

     

    CountDownLatch应用场景:线程协调使用的时减法操作,用于并行计算的时候,如果某一个处理过程运算量特别大,可以将这个任务拆分成很多个小的子任务,等待所有子任务计算完,父任务再拿到所有子任务进行汇总,降低处理时间。

    /**
     * @Author:daboluo
     * @Date: 2019/9/29 22:45
     * @Version 1.0
     * 
     * 
     * 并行计算,计算量很大,直接拆分成子线程,最后,进行汇总
     */
    public class CountDownLatchDemo {
    
        private static CountDownLatch countDownLatch = new CountDownLatch(100);
    
        private static Long count = 0L;
    
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool();
    
            for (int i = 0; i < 100; i++) {
                exec.execute(() -> {
                    try {
                        test();
                    } finally {
                        countDownLatch.countDown();
                    }
                });
            }
            countDownLatch.await();
            System.out.println("finish : count = " + count);
        }
    
        public static void test() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count++;
            System.out.println(count);
        }
    
    }

    结果:

    。。。

    96
    97
    95
    finish : count = 100

     CyclicBarrier应用场景:线程协调使用的时加法操作,有针对出现异常的reset方法,用于统计一年的excel数据,可以开多个线程统计每一页的数据,然后再进行汇总

     

    /**
     * @Author:daboluo
     * @Date: 2019/9/29 22:45
     * @Version 1.0
     *
     * 在excel表统计银行的日均流水,每一页的日均银行流水,在计算年的流水
     *
     * cyclic计算错误的时候,可以进行reset,
     */
    public class CyclicBarrierDemo {
        
        // 可以设置内存达到屏障的时候,直接打印
        private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
    
        
        public static void main(String[] args) throws Exception{
            ExecutorService exec = Executors.newCachedThreadPool();
    
            for(int i=0;i<10;i++){
                final int threadNum = i;
                Thread.sleep(1000);
                exec.execute(()->{
                    try {
                        test(threadNum);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
    
                    }
                });
            }
            exec.shutdown();
        }
    
        public static void test(int a ) throws Exception{
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(" ready-----" + a);
    
            cyclicBarrier.await();
    
            System.out.println(" continue-----" + a);
        }
    
        /**
         *  
             ready-----0
             ready-----1
             ready-----2
             ready-----3
             ready-----4
             continue-----4
             continue-----0
             continue-----1
             continue-----2
             continue-----3
             ready-----5
             ready-----6
             ready-----7
             ready-----8
             ready-----9
             continue-----9
             continue-----5
             continue-----7
             continue-----6
             continue-----8
    
         */
    
    }

     

  • 相关阅读:
    MySQL varchar类型数据转tinyint类型
    Spring Boot实战笔记(一)-- Spring简介
    Maven学习(八)-- 使用Nexus搭建Maven私服
    Maven学习(七)-- 使用Maven构建多模块项目
    浮点型 float和double类型的内存结构和精度问题
    Maven学习(六)-- Maven与Eclipse整合
    Maven学习(五)-- 聚合与继承
    关于inline函数
    《The Cg Tutorial》阅读笔记——环境贴图 Environment Mapping
    记录最近工作中遇到的一些坑
  • 原文地址:https://www.cnblogs.com/Jemb/p/11610461.html
Copyright © 2011-2022 走看看