当前位置: 首页 > news >正文

Spring Boot集成Redis实现数据缓存

在这里插入图片描述

🌿欢迎来到@衍生星球的CSDN博文🌿
🍁本文主要学习Spring Boot集成Redis实现数据缓存 🍁
🌱我是衍生星球,一个从事集成开发的打工人🌱
⭐️喜欢的朋友可以关注一下🫰🫰🫰,下次更新不迷路⭐️
💠作为一名热衷于分享知识的程序员,我乐于在CSDN上与广大开发者交流学习。
💠我希望通过每一次学习,让更多读者了解我,也希望能结识更多志同道合的朋友。
💠在今后的日子里,我将继续努力,不断提升自己的专业技能,创造更多价值。

在这里插入图片描述

目录

  • 1.Spring Boot对Redis的支持
    • 1.1 Jedis与Lettuce的区别
    • 1.2 组件的依赖关系
  • 2.RedisTemplate
    • 2.1 操作
    • 2.2 BoundValueOperations
    • 2.3 Spring Boot项目中实现Redis数据缓存
  • 3. Redis缓存的常用操作
    • 3.1 创建与读取缓存数据
    • 3.2 删除缓存数据
    • 3.3 缓存超时失效

学习目标:

  • Spring Boot项目如何集成Redis
  • Redis实现缓存数据的创建、更新以及缓存失效操作
  • 介绍如何将Redis的相关操作封装成通用的工具类

1.Spring Boot对Redis的支持

Spring Boot提供了集成Redis的组件包spring-boot-starter-data-redis,能够非常方便地集成到项目中。spring-boot-starter-data-redis组件主要依赖spring-data-redis和lettuce库。Spring Boot 1.0默认使用的是Jedis客户端,Spring Boot 2.0版本之后改为Lettuce客户端。

1.1 Jedis与Lettuce的区别

虽然Lettuce与Jedis都是连接Redis的客户端程序,但是两者在实现上还是有些不同的:

  • Jedis在实现上直连Redis服务器,在多线程环境下是非线程安全的,除非使用连接池为每个Jedis实例增加物理连接。
  • Lettuce基于Netty的连接实例(StatefulRedisConnection)可以在多个线程间并发访问,并且是线程安全的,它支持多线程环境下的并发访问,同时也是可伸缩的设计,在一个连接实例不够的情况下可以按需增加连接实例。

因此,SpringBoot 2.0之后将之前的Jedis改成了Lettuce。

1.2 组件的依赖关系

Spring Boot提供的Redis组件spring-boot-starter-data-redis也是基于Spring Data封装的,它们之间的依赖关系如图所示。
在这里插入图片描述
如图所示,spring-boot-starter-data-redis和Spring Data Redis两者是包含与被包含的关系,或者说前者更好地封装了后者。

  • Lettuce:可伸缩的Redis客户端,基于Netty NIO框架来有效地管理多个连接。
  • Spring Data Redis:Spring Data项目中的模块,封装了多个Redis客户端,让开发者对Redis的操作更加高效便捷。
  • Spring Data:Spring框架中的重要组成部分,它极大地简化了构建基于Spring框架应用的数据操作,包括非关系数据库、Map-Reduce框架、云数据服务等,同时也支持关系数据库。
  • spring-boot-starter-data-redis:Spring Boot提供的Redis集成启动器(Starter),依赖于spring-data-redis和lettuce库。

2.RedisTemplate

Spring Boot提供的Redis组件spring-boot-starter-data-redis,其中重要的是RedisTemplate。与JdbcTemplate类似,RedisTemplate是Spring针对Redis封装的一个比较强大的模板,以方便使用。只要在所需的地方注入RedisTemplate即可,无须其他额外配置,开箱即用。

RedisTemplate有两个方法经常用到:

opsForXXX()

boundXXXOps()

XXX是value(值)的数据类型。opsForXXX获取到一个操作(Operation),但是没有指定操作的key(键),可以在一个连接(事务)内操作多个key以及对应的value;boundXXXOps获取到一个指定key的操作,在一个连接内只操作这个key对应的value。

2.1 操作

RedisTemplate针对Redis的String、List、Hash、Set、ZSet五种数据类型提供了下面五个基本类来操作对应的数据类型:

  • ValueOperations:针对String类型,实现简单的键-值操作。
  • SetOperations:针对Set类型的数据操作。
  • ZSetOperations:针对ZSet类型的数据操作。
  • HashOperations:针对Hash类型的数据操作。
  • ListOperations:针对List类型的数据操作。

它们的使用特别简单,在调用类中注入RedisTemplate,操作哪种类型的数据就调用其对应的Operations(操作)。调用示例如下:

// 作string类型
redisTemplate.opsForValue().set("key","value");
// 作Hash类型
redisTemplate.opsForHash().put("hash","test","hello");
//  操作List
redisTemplate.opsForList().leftush("list","ysxq");
//  操作Set
redisTemplate.opsForSet().add("set","ysxq");
// 操作zSet
redisTemplate.opsForZSet().add("zset","ysxq");

通过上面的示例,如果要操作String类型的数据,则调用redisTemplate.opsForValue()方法获取ValueOperations实例,最后调用set()或get()方法即可。

当然,RedisTemplate也提供了DefaultValueOperations对象操作字符串类型数据,比如set()、get()、incr()等方法。调用这些方法可以方便地存储任意的Java类型,而无须进行数据的序列化和反序列化操作。

2.2 BoundValueOperations

RedisTemplate提供了API用于对key执行bound(绑定)便捷化操作,可以通过bound封装指定的key,然后执行一系列的操作,而无须显式地再次指定key,即BoundKeyOperations将事务操作封装,由容器控制。

  • BoundValueOperations是针对String类型的绑定操作。
  • BoundSetOperations是针对Set类型的绑定操作。
  • BoundListOperations是针对List类型的绑定操作。
  • BoundZSetOperations是针对ZSet类型的绑定操作。
  • BoundHashOperations是针对Hash类型的绑定操作

例如,我们在某个类或方法中需要反复操作某个特定的key中的数据,则可以先定义对应的BoundKeyOperations,然后使用此类重复操作key中的数据,无须再调用方法中指定的key。示例代码如下:


String key = "ysxq";
// 获取Redis对value的操作对象,需要先设置key
BoundValueOperations boundTemplate = redisTemplate.boundValueOps(key);
boundTemplate.set("bound test");
// 获取vaLue
String value = boundTemplate.get();

通过上面的示例,首先定义key为“ysxq”的BoundValueOperations实例,然后在后续的操作中直接使用定义的boundTemplate实例,操作这个key对应的数据,无须在调用方法中指定key。

2.3 Spring Boot项目中实现Redis数据缓存

Spring Boot项目集成Redis非常简单,只需在项目中增加spring-boot-starter-data-redis的依赖。下面通过示例演示如何在Spring Boot项目中集成Redis。

步骤01 引入Redis依赖包。

在pom.xml中增加spring-boot-starter-data-redis的依赖:

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

步骤02 修改配置文件。

在application.properties配置文件增加有关Redis的配置:

# Redis 数据库(默认为0)
spring.redis.database=0
# Redis 服务器地址
spring.redis.host=127.0.0.1
# Redis 服务器连接端口
spring.redis.port=6379
#连接池最大连接数《使用负值表示没有限制),默认为8
spring.redis.jedis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制),默认为-1
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接,默认为10
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接,默认为9
spring.redis.jedis.pool.min-idle=2
# 超时时间
spring.redis.timeout=6000

上面的示例配置中,最主要的就是Redis的连接配置,其他的属性都可以使用默认值。

步骤03 验证测试。

配置完成之后,Redis就集成到项目中了。接下来测试Redis是否配置成功。首先创建单元测试类,注入RedisTemplate,然后调用set()方法写入缓存数据来测试Redis是否集成成功。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class TestRedisTemplate {@Autowiredprivate RedisTemplate redisTemplate;@Testpublic void testString() {//调用set()方法创建缓存redisTemplate.opsForValue().set("hello:redis", "hello spring boot");System.out.println("hello:redis: "+redisTemplate.opsForValue().get("hello:redis"));}
}

在上面的例子中,我们使用redisTemplate的set方法缓存了字符串数据“hello spring boot”,然后调用get()方法获取该缓存数据,从而验证数据是否缓存成功。

缓存数据的修改也特别简单,重新调用set()方法即可,Redis会判断key是否存在,若存在则更新缓存的数据。单击Run Test或在方法上右击,选择Run ‘testString’,运行单元测试方法,结果如图所示。

在这里插入图片描述

结果表明创建的单元测试运行成功,我们使用RedisTemplate成功创建并读取缓存数据。同时也说明Spring Boot项目成功集成Redis。

3. Redis缓存的常用操作

在实际项目中,对Redis缓存的常用操作是:创建与读取缓存数据、删除缓存数据、缓存超时等。下面通过示例演示Redis常用操作。

3.1 创建与读取缓存数据

对于常用的缓存数据的创建与读取操作,调用RedisTemplate中的set()、get()方法即可。下面通过示例演示人员信息的缓存创建与读取。

首先,创建User实体类,示例代码如下:

public class User implements Serializable {private String name;@JsonIgnoreprivate String password;private Integer age;@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh", timezone = "GMT+8")private Date birthday;@JsonInclude(JsonInclude.Include.NON_NULL)private String desc;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", password='" + password + '\'' +", age=" + age +", birthday=" + birthday +", desc='" + desc + '\'' +'}';}}

在上面的示例中,我们定义了一个普通的User实体类。需要注意的是,Redis缓存整个实体类对象就需要继承Serializable可序列化接口。

然后,创建TestRedisTemplate单元测试,添加读取、创建缓存的测试方法。示例代码如下:

    @Testpublic void testobj() {User user=new User();user.setName("ysxq");user.setPassword("123456");user.setAge(30);ValueOperations<String, User> operations=redisTemplate.opsForValue();// 调用set()方法创建缓存operations.set("user:ysxq", user);// 调用get()方法获取数据User u=operations.get("user:ysxq");System.out.println("name: "+u.getName()+",u.age:"+u.getAge());}

在上面的例子中,调用redisTemplate类的set()方法存储用户对象数据,存储成功后通过get()方法获取该缓存数据。

最后,单击Run Test或在方法上右击,选择Run ‘testString’,运行单元测试方法,结果如图所示。

在这里插入图片描述

结果表明创建的单元测试运行成功,我们使用RedisTemplate成功创建并读取缓存数据。同时也说明Spring Boot项目成功集成Redis。

3.2 删除缓存数据

有时需要把过期或者没用的缓存数据删除,应该如何实现呢?RedisTemplate提供了delete()方法来删除过期的缓存key。下面我们来测试如何删除缓存,示例代码如下:

    @Testpublic void testDelete() {ValueOperations<String, User> operations = redisTemplate.opsForValue();redisTemplate.opsForValue().set("ysxq:deletekey", "need delete");// 删除缓存redisTemplate.delete("deletekey");// 判断key 是否存在boolean exists = redisTemplate.hasKey("deletekey");if (exists) {System.out.println("exists is true");} else {System.out.println("exists is false");}}

在上面的示例中,首先创建缓存ysxq:deletekey,然后删除此key来判断数据是否存在。如图所示,输出结果表明缓存的key和对应的value字符串已经被成功删除。

在这里插入图片描述

3.3 缓存超时失效

Redis可以对存入数据设置缓存超时时间,超过缓存时间Redis就会自动删除该数据。这种特性非常适合有时效限制的数据缓存及删除的场景。下面创建一个User对象,将user数据存入Redis并设置10秒后缓存失效,然后判断数据是否存在并打印结果。

    @Testpublic void testExpire() throws InterruptedException {User user=new User();user.setName("ysxq expire");user.setAge(30);ValueOperations<String,User> operations=redisTemplate.opsForValue();// 创建缓存并设置缓存失效时间operations.set("ysxq:expire",user,1000, TimeUnit.MILLISECONDS);Thread.sleep(500);// 10秒后判断缓存是否存在boolean exists=redisTemplate.hasKey("ysxq:expire");if(exists){System.out.println("exists is true");}else {System.out.println("exists is false");}Thread.sleep(1000);// 10秒后判断缓存是否存在exists=redisTemplate.hasKey("ysxq:expire");if(exists) {System.out.println("exists is true");}else {System.out.println("exists is false");}}

单击Run Test或在方法上右击,选择Run ‘testExpire’,运行单元测试方法,结果如图所示。

在这里插入图片描述

结果表明Redis缓存中已经不存在之前插入的数据,这说明该数据已经过期并被删除。在这种测试方法中可以使用hasKey方法判断key是否存在。

相关文章:

Spring Boot集成Redis实现数据缓存

&#x1f33f;欢迎来到衍生星球的CSDN博文&#x1f33f; &#x1f341;本文主要学习Spring Boot集成Redis实现数据缓存 &#x1f341; &#x1f331;我是衍生星球&#xff0c;一个从事集成开发的打工人&#x1f331; ⭐️喜欢的朋友可以关注一下&#x1faf0;&#x1faf0;&…...

CentOS 7 安装Libevent

CentOS 7 安装Libevent 1.下载安装包 新版本是libevent-2.1.12-stable.tar.gz。&#xff08;如果你的系统已经安装了libevent&#xff0c;可以不用安装&#xff09; 官网&#xff1a;http://www.monkey.org/~provos/libevent/ 2.创建目录 # mkdir libevent-stable 3.解压 …...

线性代数的本质——几何角度理解

B站网课来自 3Blue1Brown的翻译版&#xff0c;看完醍醐灌顶&#xff0c;强烈推荐&#xff1a; 线性代数的本质 本课程从几何的角度翻译了线代中各种核心的概念及性质&#xff0c;对做题和练习效果有实质性的提高&#xff0c;下面博主来总结一下自己的理解 1.向量的本质 在物…...

SSH key 运作方式

1、本地创建SSH key pairs 2、把public key上传到网站服务器&#xff08;如GitHub 3、当使用ssh方式连接时 本地SSH client向远端请求ssh连接远端发来random data要求加密本地ssh client用private key加密&#xff0c;把加密的data发送过去&#xff08;不发送private key远端接…...

【基于MBD开发模式的matlab持续集成(一)】

基于MBD开发模式的matlab持续集成 引言 或许是感受到行业内卷的愈加激烈&#xff0c;在传统制造和高新技术相结合的新能源领域对软件工程开发的要求也愈加提高&#xff0c;尤其在互联网已经大行 其道的敏捷开发&#xff0c;便顺其自然的被新能源的老板们所看重。 概述 本文…...

Linux学习记录——이십팔 网络基础(1)

文章目录 1、了解2、网络协议栈3、TCP/IP模型4、网络传输1、同一局域网&#xff08;子网&#xff09;2、局域网通信原理3、跨一个路由器的两个子网4、其它 详细的网络发展历史就不写了 1、了解 为什么会出现网络&#xff1f;一开始多个计算机之间想要共享文件&#xff0c;就得…...

CSS动效合集之实现气泡发散动画

前言 &#x1f44f;CSS动效合集之实现气泡发散动画&#xff0c;速速来Get吧~ &#x1f947;文末分享源代码。记得点赞关注收藏&#xff01; 1.实现效果 2.实现步骤 定义一个数组bubbles&#xff0c;用来存储气泡列表的基本新&#xff0c;w表示宽高&#xff0c;x表示绝对定位…...

六、串口通信

六、串口通信 串口接口介绍使用串口向电脑发送数据电脑发送数据控制LED灯 串口接口介绍 SBUF是串口数据缓存器&#xff0c;物理上是两个独立的寄存器&#xff0c;但占用相同的地址。写操作时&#xff0c;写入的是发送寄存器&#xff1b;读操作时&#xff0c;读出的是接收寄存器…...

如何将 JavaScript Excel XLSX 查看器添加到Web应用程序

在 JavaScript 中创建 Excel 查看器可能是一项艰巨的任务&#xff0c;但使用 SpreadJS JavaScript 电子表格&#xff0c;创建过程要简单得多。在本教程博客中&#xff0c;我们将向您展示如何使用 SpreadJS 的强大功能来创建一个查看器&#xff0c;该查看器允许您在 Web 浏览器中…...

网安周报|CISA发布增强开源安全性的计划

1、CISA发布增强开源安全性的计划 美国一家领先的安全机构发布了一项期待已久的计划&#xff0c;详细说明了它将如何增强联邦政府和整个生态系统的开源安全性。美国网络安全和基础设施安全局&#xff08;CISA&#xff09;开源软件安全路线图在安全开源峰会上发布。据估计&#…...

使用 Docker 安装 Elasticsearch (本地环境 M1 Mac)

Elasticsearchkibana下载安装 docker pull elasticsearch:7.16.2docker run --name es -d -e ES_JAVA_OPTS“-Xms512m -Xmx512m” -e “discovery.typesingle-node” -p 9200:9200 -p 9300:9300 elasticsearch:7.16.2docker pull kibana:7.16.2docker run --name kibana -e EL…...

Visual Studio中MD与MT的区别及运行库类型选择

MT与MD的区别 /MT&#xff1a;是multithread-static version&#xff0c;是多线程静态版本的意思&#xff0c;项目会使用运行时库的多线程静态版本&#xff0c;编译器会将LIBCMT.lib放入.obj文件中&#xff0c;以便链接器使用LIBCMT.lib解析外部符号&#xff1b;/MTd&#xff…...

Vue3函数式编程

文章目录 前言一、三种编程风格1.template2.jsx/tsx3.函数式编写风格 二、函数式编程1.使用场景2.参数3.例子3.render渲染函数 总结 前言 本文主要记录vue3中的函数式编程以及其他编程风格的简介 一、三种编程风格 1.template Vue 使用一种基于 HTML 的模板语法&#xff0c;…...

【逗老师的无线电】艾德克斯TTL串口转网口

最近手搓了一个可以用于艾德克斯ITECH电源或者电子负载的TTL串口转网口的模块&#xff0c;用上之后&#xff0c;上位机软件就可以配置以太网IP连接设备啦。就像这样。 一、ITECH TTL接口定义 二、整体逻辑 嗯&#xff0c;就这么简单。IT9000控制软件的Ethernet功能就是直接S…...

如何修改jupyter notebook默认打开路径

1、用jupyter notebook在其他位置打开自己的ipython项目&#xff1a; jupyter notebook是一个很好用的工具&#xff0c;可以保存运行结果&#xff0c;还可以给项目添加很多可视化操作与介绍文字。安装anaconda后&#xff0c;jupyter notebook就会自动安装&#xff0c;点开它会…...

【leetcode】数组排序

【leetcode】数组排序 task03 主要了解了数组中常见的排序方法&#xff1a; 1.常见数组排序方法 冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a; 冒泡排序是一种简单的排序算法&#xff0c;它多次遍历数组&#xff0c;比较相邻的元素并交换它们&#xff0c;直到整…...

【C刷题训练营】第四讲(打好基础很重要)

前言: 大家好&#xff0c;这是c语言刷题训练营的第四讲&#xff0c;打好基础便于对c语言语法与算法思维的提高&#xff0c;感谢你的来访与支持&#xff01; &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨刷题专栏…...

MySQL 某个字段存储不了内容

1. 原因 某个字段存储的内容过大 2. 解决 修改max_allowed_packet参数 max_allowed_packet参数是指mysql服务器端在一次传送数据包的过程当中最大允许的数据包大小。如果超过了设置的最大长度&#xff0c;则会数据库保持数据失败。 2.1 查询参数 show variables like %max…...

7.代理模式

1.UML 2.代码 #include <iostream> using namespace std;class Subject{ public:virtual void Request() 0; };class RealSubject:public Subject { public:virtual void Request(){cout << "RealSubject" << endl;} }; class Proxy:public Subj…...

单例模式的安全写法

要想知道怎么写单例模式&#xff0c;那么必须得知道什么是单例模式。单例模式是一种设计模式&#xff0c;它确保某个类只有一个实例&#xff0c;并且提供一个全局访问该实例的方法。单例模式不会创建实例副本&#xff0c;而是返回对已创建实例的引用。单例模式的创建可以分为两…...

牛客网SQL156

各个视频的平均完播率_牛客题霸_牛客网 方法一 select a.video_id,format(count(b.video_id)/count(a.video_id),3) 完播率 from (select uid,video_id,(end_time-start_time) 播放时长from tb_user_video_logwhere year(start_time)2021 or year(end_time)2021 ) a left joi…...

【MongoDB】docker部署社区版(一)

0、背景介绍 项目中使用MongoDB了&#xff0c;服务器挂掉&#xff0c;自己在本地搭一个试试。 1、版本选择 首先有社区版和和商业版。我选的是社区版。链接&#xff1a;https://hub.docker.com/r/mongodb/mongodb-community-server/tags 1.1、标签选择 看到标签有两个大类…...

【Graph Net学习】GNN/GCN代码实战

一、简介 GNN&#xff08;Graph Neural Network&#xff09;和GCN&#xff08;Graph Convolutional Network&#xff09;都是基于图结构的神经网络模型。本文目标就是打代码基础&#xff0c;未用PyG&#xff0c;来扒一扒Graph Net两个基础算法的原理。直接上代码。 二、代码 …...

RocketMQ 发送顺序消息

文章目录 顺序消息应用场景消息组&#xff08;MessageGroup&#xff09;顺序性生产的顺序性MQ 存储的顺序性消费的顺序性 rocketmq-client-java 示例&#xff08;gRPC 协议&#xff09;1. 创建 FIFO 主题生产者代码消费者代码解决办法解决后执行结果 rocketmq-client 示例&…...

【面试经典150 | 双指针】判断子序列

文章目录 写在前面Tag题目来源题目解题解题思路方法一&#xff1a;双指针方法二&#xff1a;动态规划 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对…...

自动驾驶信息安全方案

目录 1. 修订历史... 3 2. 概述... 4 2.1 目的... 4 2.2 适用范围... 4 2.3 参考文档... 4 2.4 术语和缩写... 4 3. 安全分析... 5 4. 总体设计... 6 4.1 ACU的安全防护... 7 4.1.1 系统安全引导... 7 4.1.2 密钥安全存储... 8 4.1.3 应…...

【云原生】kubernetes中pod(最小的资源管理组件)

目录 前言 一、pod 1.1pause容器使得Pod中的所有容器可以共享两种资源&#xff1a; 1.2 通常把Pod分为两类 1.2.1自主式Pod 1.2.2控制器管理的Pod 1.3 Pod 容器的分类 1.3.1基础容器&#xff08;infrastructure container&#xff09; 1.3.2初始化容器&#xff08;initc…...

[DB]数据库--lowdb

[DB]数据库--lowdb lowdb基本应用获取数据数据变更写入文件 lodash的使用获取数据lodash方法使用数据变更写入文件 lowdb lowdb ,是一个基于文件存储的非关系型数据库 基于loadsh的轻量级数据库 可用于在json中存储数据&#xff0c;大小一般为0~200M的json文件 方便简单的数…...

Kotlin | 在for、forEach循环中正确的使用break、continue

文章目录 for循环中使用break、continueLabel标签forEach中如何退出循环资料 Kotlin 有三种结构化跳转表达式&#xff1a; return&#xff1a;默认从最直接包围它的函数或者匿名函数返回。break&#xff1a;终止最直接包围它的循环。continue&#xff1a;继续下一次最直接包围…...

【C++】详解std::mutex

2023年9月11日&#xff0c;周一中午开始 2023年9月11日&#xff0c;周一晚上23&#xff1a;25写完 目录 概述头文件std::mutex类的成员类型方法没有std::mutex会产生什么问题问题一&#xff1a;数据竞争问题二&#xff1a;不一致lock和unlock死锁 概述 std::mutex是C标准库中…...

网站seo关键词排名推广/seo公司seo教程

Linux操作系统上安装oracle 10g&#xff0c;在启动dbca的时候报 Exception in thread "main" 错误&#xff0c;详细内容如下&#xff1a;[oraclecentos ~]$ dbca Exception in thread "main" [oraclerac1 ~]$ 经检查dbca的log如下&#xff1a;[oraclecento…...

全国网站制作公司排名/网络营销的六大特征

额的本本上两个版本不一样的XP,早就想卸载掉一个&#xff0c;最头疼的是两个XP都在C盘&#xff0c;搞的C盘好乱啊&#xff01;闲来没事就想在俺的本本上装个Linux系统&#xff0c;做了U盘启动盘后进入PE&#xff0c;就不知道怎么搞了&#xff0c;因为如果使用ghost的话&#xf…...

青海建设厅报名网站/大型营销型网站制作

隐式数据类型转换介绍前面有总结过 JS数据类型转换 Number(), toString(), parseInt()等都是属于强制转换。有时我们遇到当运算符在运算时&#xff0c;如果两边数据类型不统一&#xff0c;CPU无法计算&#xff0c;这是编译器会自动将运算符两边的数据做一个数据类型转换&#x…...

wordpress chuxia主题/个人模板建站

最近松松团队负责技术的同事任经理跟杰哥爆料&#xff0c;昨天整理公司域名偶然发现&#xff0c;各大域名商都没有.win顶级域名了&#xff0c;都将开始不在提供.win顶级域名服务&#xff0c;国内现有.win顶级域名也将转移到海外注册商。 根据松松团队任经理提供的阿里云通知显示…...

做网站还有希望吗/seo视频教程汇总

1. 什么是单页面应用程序 单页面应用程序&#xff08;英文名&#xff1a;Single Page Application&#xff09;简称 SPA&#xff0c;顾名 思义&#xff0c;指的是一个 Web 网站中只有唯一的一个 HTML 页面&#xff0c;所有的功能 与交互都在这唯一的一个页面内完成。 2. 什么…...

佛山搭建建网站哪家好/seo关键词优化排名软件

欢迎来到梁钟霖个人博客网站。本个人博客网站提供最新的站长新闻,各种互联网资讯。 还提供个人博客模板,最新最全的java教程,java面试题。在此我将尽我最大所能将此个人博客网站做的最好! 谢谢大家,愿大家一起进步! 背景 既然我们已经使用springbootdubbo 那么也不放继续深…...