自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(23)
  • 收藏
  • 关注

原创 【Java 多线程】AQS 介绍

AQS 即 AbstractQuenedSynchronizer,抽象式队列同步器,是可以给我们实现锁的一个框架,内部实现关键是维护了一个先进先出的虚拟队列,以及 state 状态变量,队列存储的载体是 Node 节点,节点标识这当前的状态值,是独占锁还是共享锁以及它的前驱节点和后继节点简单来说,就是 AQS 定义了模板,具体实现由各个子类完成,子类无非就是实现对于共享资源state的获取和释放,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在上层已经帮我们实现好了。

2024-04-22 14:37:48 571

原创 【Java 多线程】Volatile 详解

为了让各个处理器的缓存是一致的,实现了缓存一致性协议(EMSI),每个处理器会在总线上嗅探自己的缓存是不是过期了,档处理器发现自己的缓存有过期的,则将自己对应的缓存行状态设置为无效,当处理器重新读取这个数据的时候,会从内存中重新读取。对一个 volatile 变量的赋值程序通过反编译可以看到,在 volatile 修饰的共享变量进行写操作的时候会多出 lock 前缀的指令。对于一个 volatile 变量的写操作,JVM 会向处理器发送一条 lock 指令,将这个变量所在的缓存行的数据写回内存中。

2024-04-22 14:36:15 245

原创 【Java 多线程】Synchronized

偏向锁状态下,线程要获取锁时,会在 MarkWord 中直接记录线程 ID,只要线程来执行代码了,会对比线程 ID 是否相等,相等直接获取锁,执行同步代码,不相等则尝试使用 CAS 修改 MarkWord 中的线程 ID ,如果修改成功则获取锁,修改不成功说明有竞争,因此会撤销偏向锁升级为轻量级锁。在内存中,对象一般由三部分组成,分别是对象头、实际数据和对齐填充,重点在与对象头,对象头中有一个我们比较关注的部分,MarkWord,MarkWord 中记录了有关锁的信息包括锁标记位,是否为偏向锁等。

2024-04-19 10:53:09 1020

原创 【Java】HashMap 源码阅读

HashMap 主要用来存放键值对,实现了基于哈希表的 Map 接口,非线程安全。HashMap 可以存放 null 的 key 和 null 值,但 null 作为 key 只能有一个,null 作为 value 可以有多个。HashMap 的默认大小为16,之后每次扩充,容量都变为原来的2倍,并且 HashMap 总是以2的幂作为哈希表的大小。

2024-04-10 15:00:14 752 1

原创 【Java】ArrayList 源码阅读

ArrayList 底层数据结构是可变大小的数组,继承自实现ListCloneable接口。

2024-04-10 14:55:16 352 1

原创 【I/O】基于事件驱动的 I/O 模型---Reactor

假设我们现在有一个服务器,想要对接多个客户端,那么最简单的方法就是服务端为每个连接都创建一个线程,处理完业务逻辑后,随着连接关闭线程也要销毁,但是这样线程创建和销毁,不仅会带来性能开销也会带来资源浪费,如果同时有几万个连接,创建几万个线程是不现实的。

2024-04-10 10:52:22 966 1

原创 【I/O】Unix IO 介绍

对于一个套接字上的输入操作,通常第一步是等待数据从网络中到达,当数据到达时,先将数据复制到内核缓冲区中,第二步就是将数据从内核缓冲区中复制到应用进程的缓冲区中。

2024-04-08 15:05:50 723 1

原创 Raft 协议

Raft 使用一种心跳机制来触发领导者选举。

2024-03-21 11:21:29 912 1

原创 【Redis】Redis底层数据结构

为了实现键和值的快速访问,Redis 采用了一个哈希表来存储所有的键值对。一个哈希表就是一个数组,数组的每个元素称为一个哈希桶。所以不管是 String 还是集合,哈希桶的元素都是指向他们的指针。

2024-03-07 09:41:00 800 2

原创 【Redis】Redis 作为缓存要知道的那些事儿

删除缓存值或更新数据库失败而导致数据不一致,你可以使用消息队列机制确保删除或更新操作成功。在删除缓存值、更新数据库的这两步操作中,有其他线程的并发读操作,导致其他线程读取到旧值,应对方案是延迟双删或者更新与读取操作进行异步串行化。

2024-03-06 16:29:38 1027

原创 【Mit6.824】实验-Lab4-Shard KV Service

shardCtler 是一个分片控制器

2024-03-06 15:27:24 903

原创 【Mit6.824】实验-Lab3- KV Service

lab3A需要在lab2的raft基础上封装一个应用层,完成服务端和客户端的逻辑,实现一个分布式kv数据库,实现put,get,append功能。以下Op所代表的是put,get,append操作。

2024-03-06 15:25:38 363

原创 【Mit6.824】实验-Lab2D-Raft 日志压缩

对于一个长期运行的服务来说,永远记住完整的 Raft 日志是不切实际的。如果没有压缩⽇志的⽅法,最终将导致可⽤性问题:即服务器存储空间不⾜,或者 启动时间太⻓。因此,任何实际系统都需要某种形式的⽇志压缩。

2024-03-06 15:21:28 304

原创 【Mit6.824】实验-Lab2C-Raft 持久化

通过添加保存和恢复持久状态的代码,完成raft.go中的persist()和函数,需要将状态编码(或“序列化”)为字节数组,以便将其传递给Persister。使用labgob编码器。根据Raft论文,我们只需要持久化 currentTerm, votedFor 和 logs 三个数据。persist():将状态持久化到磁盘中:当节点重启时,会重新读取状态恢复在更改 currentTerm, votedFor 和 logs 的地方我们都需要调用persist()方法进行持久化。

2024-03-06 15:18:24 365

原创 【Mit6.824】实验-Lab2B-Raft 日志复制

一旦领导者被选举出来,他就开始为客户端提供服务,客户端的请求包含一条被复制状态机执行的指令,领导者把这条指令作为一条新的日志条目附加到日志中去,然后并行的发送RPCs给其他服务器。

2024-03-06 15:17:31 420 3

原创 【Mit6.824】Lab2A-Raft 领导人选举

每次请求和响应时,都要先判断,如果 term > currentTerm,要转换角色为 Follower每个 term 只能 voteFor 其他节点一次candidates 请求投票时间是随机的,注意随机性得到大多数选票后立即结束等待剩余RPC成为 Leader 后要尽快进行心跳,否则其他节点又将变成 Candidate。

2024-03-06 15:16:16 863

原创 【Mit6.824】Lab1 MapReduce

MapReduce的思想是,应用程序设计人员和分布式运算的使用者,只需要写简单的Map函数和Reduce函数,而不需要知道任何有关分布式的事情,MapReduce框架会处理剩下的事情。Map函数使用一个key和一个value作为参数。入参中,key是输入文件的名字,value是输入文件的内容。Reduce函数的入参是某个特定key的所有实例(Map输出中的key-value对中,出现了一次特定的key就可以算作一个实例)。

2024-03-06 15:12:51 340

原创 【分布式基础】分布式系统

分布式系统一定是由多个节点组成的系统,节点指的是计算机服务器,多个节点之间并不是孤立的,而是通过网络互通的,相互协作完成任务。分布式系统的设计目标是协调多个节点的行为,使其对用户呈现一个同一和协调的系统。

2024-03-06 15:00:55 286

原创 【分布式基础】分布式事务解决方案

两阶段提交,就是字面意思,分两阶段提交。有两个角色,一个负责协调各个本地资源的管理器,另一个便是,一般是数据库。事务管理器在第一阶段会向各个本地资源管理器发送一个 Prepare 消息,询问资源管理器是否准备就绪,如果事务管理器收到的回复都是 yes,则在第二阶段发送 commit 消息进行提交事务,如果其中任意一个资源管理器回复的是 no 则回滚事务。解决方案:引入超时机制,如果长时间没有收到响应,则执行特定的动作解决方案:单点故障的常规解决方案即为引入多副本机制,在主节点挂掉之后重新选主。

2024-03-06 14:59:56 853

原创 【分布式基础】分布式事务

事务提供了一种机制,在一次操作中可能涉及到多步操作,事务可以保证这一系列操作“要么全部完成,要么什么都不做”,只要这一系列操作中有一步失败,那么在这之前的操作都要。

2024-03-06 14:56:31 1240

原创 【分布式基础】分布式锁

当我们遇到同一方法在同一时间只能让一个线程来执行,那么在单机环境下,我们不需要考虑分布式锁,只需要使用 Java 相应的 API 即可。但是当我们的系统是分布式部署的时候,就不能仅在线程方面考虑锁的问题了,分布式环境下与单机环境最大的不同不是多线程而是。多线程由于可以共享堆内存,因此可以简单的采取内存作为标记存储位置,而进程之间可能彼此都不在一个物理机上,因此需要将标记存储在一个所有进程都能看得到的地方。

2024-03-06 14:43:07 346

原创 Java 从源码文件(.java)到代码执行过程发生了什么?

我们都知道 Java 是一门一次编译到处运行的语言,这与 JVM 有很大的关系,当我们执行 Java 程序的时候,会把一个一个的 .java 文件转化成 JVM 可以理解的 class 文件,然后又 JVM 去执行,注意这里的 JVM 是分操作系统的,所以可以做到一次编译,到处运行。那么Java 从源码文件(.java)到代码执行过程发生了什么?简单总结就是四个步骤:编译 --> 加载 --> 解释 --> 执行。...

2022-06-27 20:33:01 333 1

原创 多台云服务器的 Kubernetes 集群搭建

多台云服务器的 Kubernetes 集群搭建

2022-06-25 12:11:45 778

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除