<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[LiFormJie的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/LiFormJie</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; LiFormJie]]></copyright><item><title><![CDATA[Volatile内存屏障]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/124393616</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/124393616</guid><author>LiFormJie</author><pubDate>Sun, 24 Apr 2022 22:47:35 +0800</pubDate><description><![CDATA[内存屏障四种类型：
1.1、Load指令和Store指令
Load指令(读屏障)：将内存的数据拷贝到处理器缓存
Store指令(写屏障):让当前线程写入缓存的数据可以被其他线程看见
1.2、LoadLoad Barriers
排队，当第一个读屏障指令读取数据完毕之后，后一个读屏障指令才能够进行加载读取
（禁止读和读的重排序）
1.3、StoreStore Barriers
当A写屏障指令写完之后且保证A的的写入可以被其他处理器看见，再进行B的写入操作
（禁止写与写的重排序）
1.4、LoadStore Ba]]></description><category></category></item><item><title><![CDATA[集合的快速失败（fail-fast）]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/124239680</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/124239680</guid><author>LiFormJie</author><pubDate>Mon, 18 Apr 2022 00:21:07 +0800</pubDate><description><![CDATA[fail-fast（识别并发、报告异常）：
基于Java集合(Collection)的一种错误检测机制，当一个线程对某个集合进行操作时，别的线程会因为该机制无法修改集合的结构。
(fail-fast)ConcurrentModificationException：集合修改失败（并发修改异常）。
当A线程对集合进行结构修改（add、remove、clear）时，会修改集合的modCount（mod数量）。如果此时B线程进入修改集合，在next和remove迭代时，将会判断modCount是否相等，如果不相等，]]></description><category></category></item><item><title><![CDATA[JVM双亲委派]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/124097036</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/124097036</guid><author>LiFormJie</author><pubDate>Mon, 11 Apr 2022 13:22:47 +0800</pubDate><description><![CDATA[JVM双亲委派机制：
类加载：类加载时线程互斥，所以可以通过内部类进行创建
类加载原理：
向上加载向下委派
当类进行加载时，会寻找他的父类（递归），寻找到最高的父类时向下委派加载，直到不可向下委派为止。
约基础的类由约上层的加载器进行加载，但是如果基础类有调用回用户类-&gt;线程上下文类加载器
1、防止类重复加载无意义消耗资源。
2、防止核心类被用户类篡改加载。
双亲委派机制三次破坏：
第一次：
版本问题，双亲委派机制在JDK1.2引入。但类加载器和抽象类CLassLoader在JDK1.0就已经存在，面]]></description><category></category></item><item><title><![CDATA[JVM加载]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/124097025</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/124097025</guid><author>LiFormJie</author><pubDate>Mon, 11 Apr 2022 13:22:15 +0800</pubDate><description><![CDATA[加载：
预加载：当系统被启用时直接加载需要的资源到内存中
懒加载：双重检查锁，通过双重判断进行检查是否需要创建实例，如果实例是null，第二次检查为同步锁-&gt;原因：当前实例是null，而在JVM中new和赋值是异步行为
类加载器：
类加载器：通过一个类的全限定名(绝对路径)来获取这个类的二进制字节流
类加载器作用:将编译后的class文件加载到内存中
类加载器分类：
启动类加载器：加载java的基础类，但由于涉及虚拟机本地实现细节（属于虚拟机实现的一部分），所以不允许被直接引用
URL[] urls ]]></description><category></category></item><item><title><![CDATA[Java类加载器]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123947907</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123947907</guid><author>LiFormJie</author><pubDate>Mon, 04 Apr 2022 01:52:00 +0800</pubDate><description><![CDATA[类加载器：
类加载器：通过一个类的全限定名(绝对路径)来获取这个类的二进制字节流
类加载器作用:将编译后的class文件加载到内存中
类加载器分类：
启动类加载器：加载java的基础类，但由于涉及虚拟机本地实现细节（属于虚拟机实现的一部分），所以不允许被直接引用
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
扩展类加载器：加载jre/lib/ext扩展的jar包，可以直接被使用
URL[] urls = ((URLClas]]></description><category></category></item><item><title><![CDATA[Java类加载]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123946856</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123946856</guid><author>LiFormJie</author><pubDate>Mon, 04 Apr 2022 01:51:26 +0800</pubDate><description><![CDATA[加载：
预加载：当系统被启用时直接加载需要的资源到内存中
懒加载：双重检查锁，通过双重判断进行检查是否需要创建实例，如果实例是null，第二次检查为同步锁-&gt;原因：当前实例是null，而在JVM中new和赋值是异步行为
类记载过程：
装载（Load）
通过全限定名获取类的字节流，将字节流转换为方法区运行的数据结构，再通过JVM堆生成class对象去访问数据
链接（Link）
文件格式验证：class文件格式
元数据验证：Java代码规范
字节码验证：字节码语义
符号引用验证：解析正常执行
初始化（In]]></description><category></category></item><item><title><![CDATA[mysql-checkpoint]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123785455</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123785455</guid><author>LiFormJie</author><pubDate>Mon, 28 Mar 2022 01:35:59 +0800</pubDate><description><![CDATA[checkpoint：
缩短数据库的恢复时间
缓存空间不够用时，将脏页刷新到磁盘
(重做)缓存日志不可用时，刷新脏页
sharp checkpoint：完全检查点，数据库正常关闭则将脏页全部写入磁盘
uzzy checkpoint：模糊检查点，数据库运行时将脏页部分写入磁盘
部分写入：
1、master thread checkpoint
按照1s/10s时间写入一定比例的脏页到磁盘
2、flush_lru_list checkpoint
检查LRU(热点数据列表算法)列表是否有足够的空闲页数支撑用户查询，]]></description><category></category></item><item><title><![CDATA[valatile]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123784690</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123784690</guid><author>LiFormJie</author><pubDate>Mon, 28 Mar 2022 00:57:49 +0800</pubDate><description><![CDATA[valatile：
保证变量的内存可见性
禁止指令重排序
内存可见性：当A线程改变某个变量的值时，其他线程读取时是最新的值
总线嗅探机制：基于主内存的处理器，当变量的地址值被改变时，重新从主内存读取内存地址到线程中，保证在线程中的变量可见性
问题：虽然valatile保证了线程变量的可见性，但在修改时依然是线程不安全的(读-&gt;写)。可以加锁或者使用原子类处理(AtomicInteger)
指令重排序：
步骤：

例如：B需要使用A的值，那么B一定排在A后面。基于内存可见性，让线程中的变量也会基于这一点]]></description><category></category></item><item><title><![CDATA[多路IO模型]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123784376</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123784376</guid><author>LiFormJie</author><pubDate>Sun, 27 Mar 2022 23:33:54 +0800</pubDate><description><![CDATA[IO操作：将数据从硬盘空间加载到操作系统缓存区-&gt;比如JVM内存空间,再将内存空间的数据拷贝到内存地址，然后调用输入/输出
IO类型：
同步阻塞：读取时无数据则挂起，直到有数据后被主动调用
同步非阻塞：一直轮询,每次读取时直接返回错误或者资源不可用，反复调用直到成功
IO驱动：给一个注册回调机制，当内核数据就绪时向进行发送一个信号，然后进行IO处理
多路复用：初始链接时，加入一个选择器(selector)对数据批量进行监听，当有数据就绪时直接返回状态，再让进程进行处理
异步IO：进程发起时带有内核传递]]></description><category></category></item><item><title><![CDATA[redis持久化]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123469497</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123469497</guid><author>LiFormJie</author><pubDate>Mon, 14 Mar 2022 00:13:23 +0800</pubDate><description><![CDATA[数据持久化：
RDB：将数据按照一定时间内修改数据的次数将数据快照保存到磁盘中。可以修改策略使保存策略修改为：每次有数据修改保存、每秒保存、不保存三种情况
AOF：记录每次redis操作的语句，但由于操作次数较多，所以记录的数据文件相对较大，并且由于AOF的持久化会重新执行AOF记录的语句，所以同步时间相对较长
一般采用RDB+AOF的方式进行数据存储
延时双删：当数据需要与数据库保持同步时可以采用延时双删策略，即先删redis数据再修改数据库数据，延迟时间确保数据成功修改，再次删除redis缓存数据以此来]]></description><category></category></item><item><title><![CDATA[redis数据结构]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123469484</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123469484</guid><author>LiFormJie</author><pubDate>Mon, 14 Mar 2022 00:11:28 +0800</pubDate><description><![CDATA[五种数据类型：string、map、list、set、zset
数据结构
SDS：基于C语言构建的简单动态字符串，定义了字符串的长度、数量和字节数组。当需要进行插入时可以直接判断len长度，如果长度不够则会进行扩展。而由于SDS定义了len长度和free数量，所以可以进行空间预分配时扩容的长度会比实际长度多，可以避免多次扩展；同样，在缩短字符时可以通过记录数量进行后续使用。并且SDS是通过二进制存储数据，且保留了ｃ语言字符串null字符串结尾的习惯，即可以使用部分c语言的字符串函数
链表：定义了len来获取]]></description><category></category></item><item><title><![CDATA[mysql事务隔离]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123321210</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123321210</guid><author>LiFormJie</author><pubDate>Mon, 07 Mar 2022 01:19:42 +0800</pubDate><description><![CDATA[mysql事务隔离级别：
可重复读rr：mysql默认事务隔离级别，从事务开启时读取的数据进行快照，在数据未被其他事务提交更改时，每次读取的数据都是一样的
读已提交rc：只能读取到已经提交的事务
读未提交ru：可以读取到其他事务未提交的修改数据
串行化：有且只能有一个事务访问数据库
MVCC多并发版本控制：数据库会记录当前数据的最后一次的事务id、最后记录的修改日志、隐式自增主键和读视图，当多个事务进入修改时数据库会通过日志查找最大事务id+1，来执行下一次的事务。

...]]></description><category></category></item><item><title><![CDATA[mysql读取问题]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123321155</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123321155</guid><author>LiFormJie</author><pubDate>Mon, 07 Mar 2022 01:14:50 +0800</pubDate><description><![CDATA[脏读：当在未提交的情况下，事务读取到尚未提交的修改数据，此时前一个事务提交失败进行了回滚操作，那么该事务读取到i的数据称之为脏数据，此次读取称之为脏读
幻读、不可重复读：没有对读取进行快照处理，同一个事务中会因为另一个事务的修改而造成两次读取的数据不一样。幻读产生于另一个事务的insert操作，不可重复读产生于delete、update操作
第一类丢失更新：
当A事务先读取到数据，在做业务处理时，B事务对数据进行了更改并提交，然后A事务被回滚了，数据回到了A事务读取之前，此时会丢失B事务的更改操作。即第一类]]></description><category></category></item><item><title><![CDATA[mysql事务隔离级别]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123321082</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123321082</guid><author>LiFormJie</author><pubDate>Mon, 07 Mar 2022 00:58:59 +0800</pubDate><description><![CDATA[可重复读rr：mysql默认事务隔离级别，从事务开启时读取的数据进行快照，在数据未被其他事务提交更改时，每次读取的数据都是一样的
读已提交rc：只能读取到已经提交的事务
读未提交ru：可以读取到其他事务未提交的修改数据
串行化：有且只能有一个事务访问数据库
MVCC多并发版本控制：数据库会记录当前数据的最后一次的事务id、最后记录的修改日志、隐式自增主键和读视图，当多个事务进入修改时数据库会通过日志查找最大事务id+1，来执行下一次的事务。

...]]></description><category></category></item><item><title><![CDATA[mysql锁]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123320803</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123320803</guid><author>LiFormJie</author><pubDate>Mon, 07 Mar 2022 00:50:25 +0800</pubDate><description><![CDATA[一、mysql锁类型
行锁、表锁、共享锁、排他(独享)锁
表锁：对整张表进行加锁，当表被加锁时，整张表不可被修改；
1、由于是整张表加锁，所以该锁颗粒较大更容易产生加锁冲突；
2、因为不需要通过索引定位到对应的数据，所以加锁的速度更快；
3、因为表锁一次性锁住了整张表，所以相对来说并发更低
备注：当手动锁定整张表时，需要同时锁定表的所有别名，否则会报错

查看表锁的使用情况：show status like ‘table%’;
行锁：对表中的行数据进行加锁，当行数据被加锁时，同样不可被修改；
1、因为是行级]]></description><category></category></item><item><title><![CDATA[线程-线程池]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123170159</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123170159</guid><author>LiFormJie</author><pubDate>Sun, 27 Feb 2022 21:03:50 +0800</pubDate><description><![CDATA[线程池介绍：
开辟一片内存空间管理尚未死亡的线程，通过线程池进行线程调度

线程池类型：
固定尺寸的线程池：
固定了线程数量，加入线程数超过最大线程池最大线程数时，进入该线程池需要等待
单任务线程池：
线程池只持有一个线程，后续线程进入线程池需要等待，使用无界队列进行管理
ps：
无界队列：底层采用CAS自选进行队列管理，系统资源耗尽前没有空间上限
可变尺寸连接池：
线程池尺寸不定，没有大小限制
延迟连接池：
可以使线程进行延迟启动或者定期启动
单任务延迟连接池：
单线程延迟启动
自定义线程池：
自定义线程]]></description><category></category></item><item><title><![CDATA[线程基础篇]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/123168971</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/123168971</guid><author>LiFormJie</author><pubDate>Sun, 27 Feb 2022 20:40:32 +0800</pubDate><description><![CDATA[线程组成：
一个指向当前被执行指令的指令指针：IP寄存器，指向对应线程
一个栈：对线程的一个快照存储，记录了所有线程的运行状态，包括调用堆栈，锁池情况等
一个寄存器值的集合：定义了一部分描述正在执行线程的处理器状态的值
一个私有的数据区：该线程私有的数据
线程启动：
通过实现 Runnable 接口：
由于是实现接口，所以可以继承其他线程，多线程可以共用同一个对象，将cpu代码和对象分开，模型清晰。
需要访问当前线程，必须使用Thread.currentThread()方法。
通过继承 Thread 类本身]]></description><category></category></item><item><title><![CDATA[Java锁同步synchronized]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/122912222</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/122912222</guid><author>LiFormJie</author><pubDate>Sun, 13 Feb 2022 19:19:41 +0800</pubDate><description><![CDATA[synchronized同步的位置：
1、普通同步方法，锁是当前实例对象；
2、静态同步方法，锁是当前类的class对象；
3、同步方法块，锁是括号里面的对象。
synchronized存于Java对象头中
虚拟机的对象头主要包括两部分数据：Mark Word（标记字段）、Klass Pointer（类型指针）。
Mark Word：存储对象自身的运行时数据
例如：哈希码（HashCode）、GC分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等等

当Java对象头的Mark Word发生锁]]></description><category></category></item><item><title><![CDATA[Java锁升级]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/122912000</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/122912000</guid><author>LiFormJie</author><pubDate>Sun, 13 Feb 2022 18:26:18 +0800</pubDate><description><![CDATA[锁状态：无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态
线程锁：
通常线程锁都是为了保证多个线程抢占同一个资源时不发生问题的一种保障措施，以保证不会发生死锁。
锁升级：
无锁态：没有对资源进行加锁操作
偏向锁：如果同一个线程获取多次同一个锁，则升级为偏向锁，偏向锁会判断线程的id和资源对象的头线程id是否一致，如果一致则直接把锁交予该线程
轻量级锁：如果多个线程获取锁，则升级为轻量级锁cas，通过自旋获取锁，如果失败则直接进入到下一次循环再次获取无需等待
重量级锁：同步锁，当前只允许一个线程获取锁，进行资]]></description><category></category></item><item><title><![CDATA[Java锁类型]]></title><link>https://blog.youkuaiyun.com/LiFormJie/article/details/122910227</link><guid>https://blog.youkuaiyun.com/LiFormJie/article/details/122910227</guid><author>LiFormJie</author><pubDate>Sun, 13 Feb 2022 17:48:50 +0800</pubDate><description><![CDATA[Java锁类型
悲观锁、乐观锁
悲观锁：每次进行操作时都默认数据会被更改，对数据进行上排他锁，除了当前操作，其他线程不可访问
乐观锁：一般通过其他数据是否有被更高来确定当前数据是否未被更改，比如版本号或者时间戳，通常依赖数据库进行判断处理
自旋锁；通过判断当前数据的内存位置的值和预期值进行比对，如果比对通过则修改当前数据的值。在多线程下，其他自旋锁并不会进入等待，而是直接失败进行下一次循环判断。但是如果长时间比对失败，可能会由于自旋锁尝试次数过多导致cpu负荷过大。ABA问题：当某一个数据有A到B，再由B到]]></description><category></category></item></channel></rss>