6.2k 词
什么是消息队列?消息队列(Message Queue),字面意思就是存放消息的队列。最简单的消息队列模型包括3个角色: 消息队列:存储和管理消息,也被称为消息代理(Message Broker) 生产者:发送消息到消息队列 消费者:从消息队列获取消息并处理消息 如何实现?之前使用Java的BlockingQueue和线程池实现了简单的消息队列,但这样的实现有两个问题: 内存消耗:若消息很多,则JVM的内存可能被快速耗尽,导致内存不足 非持久性存储:JVM的内存不是持久性的,消息队列中的消息可能发生丢失 所以这里采用Redis来实现,可以很好解决上述问题(为什么不用其他中间件?因为Redis成本更低) Redis提供了三种不同的方式来实现消息队列: list结构:基于List结构模拟消息队列 PubSub:基本的点对点消息模型 Stream:比较完善的消息队列模型 基于List结构模拟消息队列实现方式使用LPUSH实现消息进入队列,BRPOP实现消息有阻塞的取出队列 该实现方法的优缺点优点 利用Redis存储,不受限于JVM内存上限 基于Redis的持久化机制,数据...
715 词
二分法,很简单啊,很早就知道这个了,不就是一直从中间取值,然后找到target吗 那么, 每次写二分法时,有没有想过,while判断条件里的left和right,究竟是<还是<=呢;更新边界时,right究竟是middle还是middle - 1呢? 至少对我来说,每次写二分这些都是随缘的,能a就行,但是大部分时候a不了 回到正题,写二分法时,最重要的就是保持区间不变 所谓区间不变,就是整个算法当中,都要明确自己的代码是左闭右闭[left, right],还是左闭右开[left, right),以下只会讲左闭右闭的情况,另外的情况就很简单了。 < 还是 <=while里的判断条件,也就是区间是否合法的条件,我们假设left和right相等,区间就是[1,1],这个区间显然合法,所以应该是<= 也不难想到,在左闭右开的情况下,是不能取等号的,因为[1, 1)显然不合法 要不要减一(加一)边界更新的前提是我们已经知道了nums[middle] != target, 此时我们的下一个搜索范围,肯定不应该包含middle了,所以应该是要加一或减一的。 ...
1.2k 词
在Spring管理的类中注入Bean对象非常容易,只需使用@Autowired或者@Resource注解即可,但是在非Spring管理的对象中,注入Bean对象却没这么简单。 这时,我们就需要自己写一个工具类了,实现很简单,代码如下: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748package com.hmdp.utils;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.lang.NonNull;import org.springframework.stereotype.Component;@Componentpublic c...
5.4k 词
虽然Java提供了 synchronized之类的方法来实现线程对临界资源的互斥访问,但是这仅仅局限于单台服务器,对于集群服务器并不适用。 Redis分布式锁 于是我们希望通过Redis来实现服务器集群的线程锁,因为Redis对于所有服务器来说是相同的,且具有较好的性能和较高的可用性。 简单实现具体实现流程如下: 代码实现先写一个锁的抽象类,因为会做多个版本的实现 123456789101112131415public abstract class ILock { /** * 尝试获取锁 * * @param timeoutSec 锁自动释放的市场(秒) * @return 是否成功获取到锁 */ abstract public boolean tryLock(long timeoutSec); /** * 释放锁 */ abstract public void unlock();} 当前版本的最基础实现 12345678910111213141516171819202122...
5.8k 词
缓存穿透 缓存穿透:对于一个缓存和数据库中都不存在的数据查询,因为每次查询都会穿过缓存直接打在数据库上,所以很容易增大数据库压力,如下图所示。 对于缓存穿透这个问题,解决方案包括但不限于如下: 缓存空对象 进行一次结果为空的数据库查询后,以该查询为key,null为value,并设置TTL,将其放进缓存,这样在下一次同样的查询时,就不会再进行数据库查询。缺点 缓存空对象会造成缓存的内存开销。 代码实现 123456789101112131415161718192021222324252627282930313233343536373839404142/** * 普通缓存查询,使用存储空对象的方法防止缓存穿透 * * @param keyPrefix key的前缀 * @param id 要查询的id * @param type 查询的实体类型 * @param dbFallBack 数据库查询方法 * @param time 新缓存的过期时间 * @param unit 时间单位 * @param <T>...
977 词
基于session完成登录时如何登出@Controller 1234567@PostMapping("/logout")public Result logout(HttpSession session){ log.info("登出"); session.invalidate(); //使当前客户端的session无效化 userService.logout(); return Result.ok();} @Service 123public void logout(HttpHeaders headers) { UserHolder.removeUser(); //清空TreadLocal的数据} 基于Redis完成登录时登出@Controller 123456@PostMapping("/logout")public Result logout(@RequestHeader HttpHeaders headers){ log....
169 词
捣鼓了一两个小时,磕磕绊绊的做好了这个博客 Hello World程序的第一句话,永远是Hello World 那么这个博客也算是我人生的Hello World吧 结束了一些事情,也下定了一些决心,为人生开启一个新的阶段吧 最近的一些小目标,应该就是写好简历,同时开始学八股吧 加油加油 希望这个博客我能一直坚持写下去吧 只要努力,一定会有一个我想要的未来的