java架构《并发线程高级篇三》
本章主要介绍和讲解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架构《并发线程高级篇三》的更多相关文章
- java架构《并发线程高级篇四》
本章主要讲并发线程的常见的两种锁.重入锁和读写锁 一:重入锁(ReentrantLock) 概念:重入锁,在需要进行同步的代码加锁,但最后一定不要忘记释放锁,否则会造成锁永远不能释放,其他线程进不了 ...
- java架构《并发线程高级篇一》
本章主要记录讲解并发线程的线程池.java.util.concurrent工具包里面的工具类. 一:Executor框架: Executors创建线程池的方法: newFixedThreadPool( ...
- java架构《并发线程高级篇二》
本章主要记录讲解并发线程的线程池.使用Executor框架自定义线程池. 自定义线程池使用Queue队列所表示出来的形式: 1 ArrayBlockingQueue<Runnable>(3 ...
- Java高并发 -- 线程池
Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...
- Java高并发--线程安全策略
Java高并发--线程安全策略 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 不可变对象 发布不可变对象可保证线程安全. 实现不可变对象有哪些要注意的地方?比如JDK ...
- Java并发-线程池篇-附场景分析
作者:汤圆 个人博客:javalover.cc 前言 前面我们在创建线程时,都是直接new Thread(): 这样短期来看是没有问题的,但是一旦业务量增长,线程数过多,就有可能导致内存异常OOM,C ...
- Java高并发与多线程(四)-----锁
今天,我们开始Java高并发与多线程的第四篇,锁. 之前的三篇,基本上都是在讲一些概念性和基础性的东西,东西有点零碎,但是像文科科目一样,记住就好了. 但是本篇是高并发里面真正的基石,需要大量的理解和 ...
- Java之创建线程的方式四:使用线程池
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...
- java架构《并发线程中级篇》
java多线程的三大设计模式 本章主要记录java常见的三大设计模式,Future.Master-Worker和生产者-消费者模式. 一.Future模式 使用场景:数据可以不及时返回,到下一次实际要 ...
随机推荐
- sa-token v1.9.0 版本已发布,带来激动人心新特性:同端互斥登录
sa-token是什么? sa-token是一个JavaWeb轻量级权限认证框架, 官网首页:http://sa-token.dev33.cn/ 如果你经常使用腾讯QQ,就会发现它的登录有如下特点:它 ...
- Logstash学习之路(二)Elasticsearch导入json数据文件
一.数据从文件导入elasticsearch 1.数据准备: 1.数据文件:test.json 2.索引名称:index 3.数据类型:doc 4.批量操作API:bulk {"index& ...
- LeetCode 长度最小的子数组
题目: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. 思路: 非常明显用滑动窗口处 ...
- 有哪些适合个人开发的微信小程序
微信小程序提供了一个简单.高效的应用开发框架和丰富的组件及API,帮助开发者在微信中开发具有原生 APP 体验的服务. 微信小程序支持采用云开发模式,无需后台服务,十分的方便快捷,适合个人开发一些工具 ...
- 【JavaWeb】Filter 过滤器
Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...
- LeetCode733 图像渲染
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newCol ...
- SpringMVC文件的上传与下载实现
单文件上传 首先创建项目,开发工具是IDEA,选择Spring项目,勾选上Spring和SpringMVC. 然后命名,最后完成. 默认生成配置文件在web/WEB-INF下. 首先导入需要的jar包 ...
- 分别使用 Python 和 Math.Net 调用优化算法
1. Rosenbrock 函数 在数学最优化中,Rosenbrock 函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock 在 1960 年提出 .也称为 R ...
- 【Jboss】A RESOURCE POOL IS PERMANENTLY BROKEN!
jboss后台报错,其中有这个错误 [error] A RESOURCE POOL IS PERMANENTLY BROKEN! 查阅多方资料后发现.数据库连接配置文件中,有地方存在空格,导致服务连接 ...
- leetcode 1593. 拆分字符串使唯一子字符串的数目最大(DFS,剪枝)
题目链接 leetcode 1593. 拆分字符串使唯一子字符串的数目最大 题意: 给你一个字符串 s ,请你拆分该字符串,并返回拆分后唯一子字符串的最大数目. 字符串 s 拆分后可以得到若干 非空子 ...