SpringBoot高级技术

博客地址: step6 SpringBoot高级技巧

异步线程池

书上讲的是什么像异步操作那样,然后不需要等待。

问题是,不需要等待,但数据在生成的时候的时间并不能省。

我们计时不是从开始到得到数据时候吗?

我觉得是多任务的时候可以用异步线程池,如:统计和拿到各大模块的数据的时候,就可以用异步多线程,或者是不需要结果的操作时。

像清理文件,这就可以用异步来做,然后直接返回信息,不需要用户等待。

更为具体的,我认为可以称之为,异步任务队列。

第一,给自己的Service 实现方法上打上@Async,然后就是异步执行了。

这个功能用来远程调用还是非常不错的。

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer { @Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数量
taskExecutor.setCorePoolSize(10);
// 线程池最大线程数
taskExecutor.setMaxPoolSize(30);
// 线程队列最大线程数
taskExecutor.setQueueCapacity(2000);
taskExecutor.initialize();
return taskExecutor;
} }

定时器 && 异步消息

用定时器可以做一些定时广播的任务,定时给用户发广告,当然这得用异步。

其中Sechuled可以配置每天什么时候,或者是隔多久执行一次

@EnableScheduling 开启全局定时器

异步消息就是在要执行方法上加上@Async,然后配置类在异步线程池那一段,但如果你的需求要用到异步的时候,请一定要想好数据安全是否得到保证。

你更不能指望这一篇博文能帮助你学会这个技术,即使一本SpringBoot的专业书也不行。


@Service
public class SystemServiceImpl implements SystemService {
@Override
@Async
@Scheduled(fixedRate = 4000)
public void backups() throws InterruptedException {
System.out.println("备份数据ing");
WebSocketServiceImpl.webSocketSet.forEach(d->{
try {
d.session.getBasicRemote().sendText("定时任务发送"+ DateUtil.formatAsDatetime(new Date()));
} catch (IOException e) {
e.printStackTrace();
}
});
Thread.sleep(3000);
System.out.println("备份数据完成");
} }

WebSocket应用

兼容除chrome,firefox之外的浏览器可能需要使用WebSocket下的子协议STOMP

对于服务端而言,需要实现特定的钩子,OnOpen,OnClose,OnMessage

然后这些钩子会帮助你进行对客户端WebSocket进行通信,相关的API可以上官网进行查看,这里只在书上看常用的,并且我还用其实现了 定时广播的功能

可以看看:SpringBoot学习地址

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

@ServerEndpoint("/ws/{username}")
@Service
public class WebSocketServiceImpl { private static int onlineCount = 0; // 每次访问对象对应的请求对象
public static CopyOnWriteArraySet<WebSocketServiceImpl> webSocketSet = new CopyOnWriteArraySet<>(); private String username;
public volatile Session session; @OnOpen
public synchronized void onOpen(Session session,@PathParam("username") String username){
this.session = session;
this.username = username;
System.out.println(this.session);
webSocketSet.add(this);
addOnlineCount();
// 为什么要用getOnelineCount,因为这个加了线程保护锁
System.out.println("新加入成功!目前总在线人数:"+getOnlineCount()); try {
sendMessage("有新的连接加入!"+session.getId());
} catch (IOException e) {
e.printStackTrace();
} }
@OnClose
public void onClose(Session session) throws IOException { webSocketSet.remove(this);
subOnelineCount();
System.out.println("有一个人退出聊天室!"+getOnlineCount());
} @OnMessage
public void onMessage(String message,Session session) throws IOException {
System.out.println("one guy send one message: "+message); // 给每个在线的用户都发送这条信息,广播? for (WebSocketServiceImpl item :
webSocketSet) {
try{ // String username = item.session.getUserPrincipal().getName();
System.out.println(item.username+":"+message);
item.sendMessage(item.username+":"+message); }catch (Exception e){
e.printStackTrace();
}
} } private void sendMessage(String msg) throws IOException {
this.session.getBasicRemote().sendText(msg);
} private static synchronized int getOnlineCount(){
return onlineCount;
}
public static synchronized void subOnelineCount(){
onlineCount--;
} public static synchronized void addOnlineCount(){
onlineCount++;
} }

<template>
<div>
<input type="text" v-model="message" placeholder="请输入信息">
<button @click="sendMessage">发送信息</button>
<button @click="closeConnection">关闭WebSocket连接</button> <p v-for="(l,i) in msgList" :key="i">{{l}}</p>
</div>
</template> <script>
export default {
name: "WebSocket",
data(){
return{
message:null,
ws:null,
msgList:[],
username:null,
}
},
created() {
this.username = prompt("请输入用户名")
this.initWebSocket()
},
methods:{
initWebSocket: function () {
var vm = this
if ('WebSocket' in window) {
vm.ws = new WebSocket("ws://localhost:8083/ws/"+vm.username); this.ws.onerror = function(){
vm.msgList.push("error")
} this.ws.onopen = () => { vm.msgList.push("open successful")
}
// 添加信息
this.ws.onmessage = (event)=>{
console.log(event,"onmessage")
vm.msgList.push(event.data)
}
} else {
alert("browser cant got websocket,nigger");
} // 窗口关闭时关闭连接
window.onbeforeunload = ()=>{
vm.ws.close()
} },
closeConnection(){
this.ws?.close()
},
sendMessage(){
console.log(this.ws)
this.ws?.send(this.message)
this.message = null
alert("send ok")
}
}
}
</script> <style scoped> </style>

重学SpringBoot. step6 SpringBoot高级技巧的更多相关文章

  1. 重学 Java 设计模式:实战外观模式「基于SpringBoot开发门面模式中间件,统一控制接口白名单场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 你感受到的容易,一定有人为你承担不容易 这句话更像是描述生活的,许许多多的磕磕绊绊总 ...

  2. 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...

  3. 重学 Java 设计模式:实战责任链模式「模拟618电商大促期间,项目上线流程多级负责人审批场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 场地和场景的重要性 射击

  4. 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相信相信的力量! 从懵懂的少年,到拿起键盘,可以写一个Hell ...

  5. 重学 Java 设计模式:实战备忘录模式「模拟互联网系统上线过程中,配置文件回滚场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 实现不了是研发的借口? 实现不了,有时候是功能复杂度较高难以实 ...

  6. 重学 Java 设计模式:实战状态模式「模拟系统营销活动,状态流程审核发布上线场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! @ 目录 一.前言 二.开发环境 三.状态模式介绍 四.案例场景模拟 1 ...

  7. 重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 能力,是你前行的最大保障 年龄会不断的增长,但是什么才能让你不 ...

  8. 12天,这本《重学Java设计模式》PDF书籍下载量9k,新增粉丝1400人,Github上全球推荐榜!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言

  9. 重学hadoop技术

    最近因为做了些和hadoop相关的项目(虽然主要是运维),但是这段经历让我对hadoop的实际运用有了更加深入的理解. 相比以前自学hadoop,因为没有实战场景以及良好的大数据学习氛围,现在回顾下的 ...

  10. Java集合类简单总结(重学)

    java集合类简介(重学) 一.Collection(集合).Map接口两者应该是平行关系吧. 1.Map介绍 Map是以键值(key-value)对来存放的,2个值.通过key来找到value(例: ...

随机推荐

  1. 面试 个人摸底监测 考察考察JS三座⼤⼭ 1. 原型和原型链 2. 作⽤域与闭包 3. 异步和单线程 (第四天)

    01.如何判断⼀个变量是不是数组? let arr = [1,2,3,4] function fun(){ return arr instanceof Array } 02.如何使⽤class实现继承 ...

  2. JAVA 用分苹果来理解本题

    思路 其实这是一道非常经典的分苹果问题:有m个一样的苹果和n个一样的盘子,把苹果放盘子里,每个盘子允许0-m个苹果,求问有多少种分法? 与本题的共通之点在于,输入的正整数可以看成m个苹果,拆分出的加数 ...

  3. Redis系列11:内存淘汰策略

    Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...

  4. 深度解析KubeEdge EdgeMesh 高可用架构

    摘要:通过高可用特性应用场景.高可用特性使用手册.课题总结.未来展望等四个部分的内容来向大家介绍新版本EdgeMesh的高可用架构. 本文分享自华为云社区<KubeEdge EdgeMesh 高 ...

  5. 关于linux上实现arp攻击截取密码

    前言 这几天简单的研究了一下arp攻击,有一些进展,记录一下 环境准备 这里我是利用arpspoof 这个软件简单实现arp攻击,这个命令是属于dsniff 软件包中的 所以首先安装软件 sudo a ...

  6. js 获取相同name元素的属性值

    如图有8-12月5个文本域,id为plan8-12,name同为plan. 现在要获取name同为plan的所有属性值: 方法一: var allplan =document.getElementsB ...

  7. 【sqoop】简介、原理、安装配置测试、导入导出案例、脚本打包、常见命令及参数介绍、常用命令举例

    一.sqoop简介 用于在Hadoop(Hive)与传统的数据库(mysql.oracle...)之间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等 ...

  8. 【每日一题】2021年12月11日-69. Sqrt(x)/x的平方根

    给你一个非负整数 x ,计算并返回 x 的 算术平方根 . 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 . 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或 ...

  9. <三>function函数对象类型的应用示例

    std::function是一组函数对象包装类的模板,实现了一个泛型的回调机制.function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数,也可以是函数 ...

  10. C# 11新特性之file关键字

    C#11 添加了文件作用域类型功能:一个新的 file 修饰符,可以应用于任何类型定义以限制其只能在当前文件中使用.这样,我们可以在一个项目中拥有多个同名的类. 目录 示例 file不可以与其他修饰符 ...