本章主要介绍和讲解concurrent.util里面的常用的工具类。

一、CountDownLatch使用:(用于阻塞主线程)

      应用场景 :通知线程休眠和运行的工具类,是wait和notify的升级版本。notify不会释放锁,但是  countDown()会释放锁

         

                      实例化:final CountDownLatch countDown = new CountDownLatch(2);

                  使用在Thread里面:   countDownLatch.countDown(); 相当于 notfiy;  特点: countDown()会释放锁
countDownLatch.await();相当于 wait;

二、CyclicBarrier使用:barrier(障碍) (用于多个阻塞线程等待,都通准备好后,一起开始执行当前线程的代码)

      应用场景:多个线程,当任何一个线程都没准备好,都阻塞。当都准备好时,都执行自己的线程。

      注意事项:多少个线程,需要多少个barrier.await();否则都会阻塞在此。

      代码解析:

          

          

 1                public class UseCyclicBarrier {
2
3             static class Runner implements Runnable {
4             private CyclicBarrier barrier;
5             private String name;
6
7             public Runner(CyclicBarrier barrier, String name) {
8               this.barrier = barrier;
9               this.name = name;
10               }
11             @Override
12             public void run() {
13               try {
14                 Thread.sleep(1000 * (new Random()).nextInt(5));
15                 System.out.println(name + " 准备OK.");
16                 barrier.await();
17                 } catch (InterruptedException e) {
18                   e.printStackTrace();
19                 } catch (BrokenBarrierException e) {
20                   e.printStackTrace();
21                 }
22                 System.out.println(name + " Go!!");
23                 }
24               }
25
26         public static void main(String[] args) throws IOException, InterruptedException {
27             CyclicBarrier barrier = new CyclicBarrier(3); // 3
28             ExecutorService executor = Executors.newFixedThreadPool(3);
29
30             executor.submit(new Thread(new Runner(barrier, "zhangsan")));
31             executor.submit(new Thread(new Runner(barrier, "lisi")));
32             executor.submit(new Thread(new Runner(barrier, "wangwu")));
33
34             executor.shutdown();
35           }
36
37         }

三、Future模式补充和Callable

         使用场景:需要大数量量处理数据的时候,异步去处理数据,提高程序的吞吐量

           注意事项:真正进行业务逻辑处理的类, 类一定实现Callable接口,重写Call()方法。

         

 1         private String para;
2
3           public UseFuture(String para){
4           this.para = para;
5           }
6
7           /**
8           * 这里是真实的业务逻辑,其执行可能很慢
9           */
10           @Override
11           public String call() throws Exception {
12           //模拟执行耗时
13           Thread.sleep(5000);
14           String result = this.para + "处理完成";
15           return result;
16         }
17
18        
19
20         String queryStr = "query";
21         //构造FutureTask,并且传入需要真正进行业务逻辑处理的类,该类一定是实现了Callable接口的类
22         FutureTask<String> future = new FutureTask<String>(new UseFuture(queryStr));
23
24         FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr));
25         //创建一个固定线程的线程池且线程数为1,
26         ExecutorService executor = Executors.newFixedThreadPool(2);
27         //这里提交任务future,则开启线程执行RealData的call()方法执行
28         //submit和execute的区别: 第一点是submit可以传入实现Callable接口的实例对象, 第二点是submit方法有返回值
29
30         Future f1 = executor.submit(future); //单独启动一个线程去执行的
31         Future f2 = executor.submit(future2);
32         System.out.println("请求完毕");
33
34           try {
35             //这里可以做额外的数据操作,也就是主程序执行其他业务逻辑
36             System.out.println("处理实际的业务逻辑...");
37             Thread.sleep(1000);
38           } catch (Exception e) {
39               e.printStackTrace();
40             }
41           //调用获取数据方法,如果call()方法没有执行完成,则依然会进行等待
42           System.out.println("数据:" + future.get());
43           System.out.println("数据:" + future2.get());
44
45           executor.shutdown();

        

        总结:FutureTask对象。当使用其get()方法时,会异步加载对应的返回结果。Future 对象。当使用其get()方法时。返回null,则表示该子线程已经完成。

           submit和execute的区别: 第一点是submit可以传入实现Callable接口的实例对象, 第二点是submit方法有返回值。

四、Semaphore信号量

        使用场景:当 系统上线之前,对系统进行信息并发量的评估。进行自动化测试。在业务逻辑层,进行限流

        相关概念:

            

                     PV(page  view) :网站总访问量,页面浏览量或点击量,每刷新一次都记录下来。

             UV(unique Visitor):访问网站的IP总数,没一个Ip,一天内只记录一次。
             QRS(Query per second):每秒的查询数。              RT(response time):访问相应时间。

        

        代码解析:

            创建一个无界阻塞的线程池。通过循环产生多个线程。每个线程里面进行业务逻辑实现。每次实现业务前。都获得semp.acquire()(许可),完成之后,都semp.release()(释放许可),做到限流。

        用法:    

          

 1               // 只能5个线程同时访问
2           final Semaphore semp = new Semaphore(5);
3
4           // 获取许可
5
6           semp.acquire();
7           System.out.println("Accessing: " + NO);
8           //模拟实际业务逻辑
9           Thread.sleep((long) (Math.random() * 10000));
10           // 访问完后,释放
11           semp.release();

        峰值计算:    

               峰值qp:(总PV*80%)/(60*60*24*20%)

             80%的访问请求将在20%的时间内达到。         

java架构《并发线程高级篇三》的更多相关文章

  1. java架构《并发线程高级篇四》

    本章主要讲并发线程的常见的两种锁.重入锁和读写锁 一:重入锁(ReentrantLock) 概念:重入锁,在需要进行同步的代码加锁,但最后一定不要忘记释放锁,否则会造成锁永远不能释放,其他线程进不了 ...

  2. java架构《并发线程高级篇一》

    本章主要记录讲解并发线程的线程池.java.util.concurrent工具包里面的工具类. 一:Executor框架: Executors创建线程池的方法: newFixedThreadPool( ...

  3. java架构《并发线程高级篇二》

    本章主要记录讲解并发线程的线程池.使用Executor框架自定义线程池. 自定义线程池使用Queue队列所表示出来的形式: 1 ArrayBlockingQueue<Runnable>(3 ...

  4. Java高并发 -- 线程池

    Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...

  5. Java高并发--线程安全策略

    Java高并发--线程安全策略 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 不可变对象 发布不可变对象可保证线程安全. 实现不可变对象有哪些要注意的地方?比如JDK ...

  6. Java并发-线程池篇-附场景分析

    作者:汤圆 个人博客:javalover.cc 前言 前面我们在创建线程时,都是直接new Thread(): 这样短期来看是没有问题的,但是一旦业务量增长,线程数过多,就有可能导致内存异常OOM,C ...

  7. Java高并发与多线程(四)-----锁

    今天,我们开始Java高并发与多线程的第四篇,锁. 之前的三篇,基本上都是在讲一些概念性和基础性的东西,东西有点零碎,但是像文科科目一样,记住就好了. 但是本篇是高并发里面真正的基石,需要大量的理解和 ...

  8. Java之创建线程的方式四:使用线程池

    import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...

  9. java架构《并发线程中级篇》

    java多线程的三大设计模式 本章主要记录java常见的三大设计模式,Future.Master-Worker和生产者-消费者模式. 一.Future模式 使用场景:数据可以不及时返回,到下一次实际要 ...

随机推荐

  1. sa-token v1.9.0 版本已发布,带来激动人心新特性:同端互斥登录

    sa-token是什么? sa-token是一个JavaWeb轻量级权限认证框架, 官网首页:http://sa-token.dev33.cn/ 如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它 ...

  2. Logstash学习之路(二)Elasticsearch导入json数据文件

    一.数据从文件导入elasticsearch 1.数据准备: 1.数据文件:test.json 2.索引名称:index 3.数据类型:doc 4.批量操作API:bulk {"index& ...

  3. LeetCode 长度最小的子数组

    题目: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. 思路: 非常明显用滑动窗口处 ...

  4. 有哪些适合个人开发的微信小程序

    微信小程序提供了一个简单.高效的应用开发框架和丰富的组件及API,帮助开发者在微信中开发具有原生 APP 体验的服务. 微信小程序支持采用云开发模式,无需后台服务,十分的方便快捷,适合个人开发一些工具 ...

  5. 【JavaWeb】Filter 过滤器

    Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...

  6. LeetCode733 图像渲染

    有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newCol ...

  7. SpringMVC文件的上传与下载实现

    单文件上传 首先创建项目,开发工具是IDEA,选择Spring项目,勾选上Spring和SpringMVC. 然后命名,最后完成. 默认生成配置文件在web/WEB-INF下. 首先导入需要的jar包 ...

  8. 分别使用 Python 和 Math.Net 调用优化算法

    1. Rosenbrock 函数 在数学最优化中,Rosenbrock 函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock 在 1960 年提出 .也称为 R ...

  9. 【Jboss】A RESOURCE POOL IS PERMANENTLY BROKEN!

    jboss后台报错,其中有这个错误 [error] A RESOURCE POOL IS PERMANENTLY BROKEN! 查阅多方资料后发现.数据库连接配置文件中,有地方存在空格,导致服务连接 ...

  10. leetcode 1593. 拆分字符串使唯一子字符串的数目最大(DFS,剪枝)

    题目链接 leetcode 1593. 拆分字符串使唯一子字符串的数目最大 题意: 给你一个字符串 s ,请你拆分该字符串,并返回拆分后唯一子字符串的最大数目. 字符串 s 拆分后可以得到若干 非空子 ...