Hello World
¶这是哪
❓这里是L Blog,用来记录我的学习笔记,更重要的是认识志同道合的好友
¶关于作者
🚶大三学生仔,目标是Java程序猿,具体请看💬关于我
¶快速开始🚀🚀🚀🚀🚀🚀🚀
¶JVM-自动内存管理与垃圾回收篇
JVM体系结构
JVM与java体系结构
类加载
类加载子系统(略)
运行时数据区:
运行时数据区概述及线程
程序计数器
虚拟机栈
本地方法接口
本地方法栈
堆
方法区
对象实例化内存布局与访问定位
直接内存
StringTable
JVM执行引擎
执行引擎
垃圾回收概述
垃圾回收相关算法
垃圾回收相关概念
垃圾回收器
¶JAVA并发核心体系
上篇:JAVA并发基础
🚁基础:线程八大核心
🚁java内存模型—底层原理
🚁死锁
🚁复习:线程基础核心-原理-死锁
下篇:JUC
🚁线程池
🚁ThreadLocal
🚁千变万化的锁
🚁原子类
🚁CAS
🚁final关键字和不变性
🚁并发容器
🚁并发流程控制
🚁AQS
🚁Future和Callable
¶设计模式
设计模式分为三种类型,共23 ...
emoji快查
¶People
人
😐 :neutral_face:
😄 :smile:
😆 :laughing:
😊 :blush:
😃 :smiley:
☺️ :relaxed:
😏 :smirk:
😍 :heart_eyes:
😘 :kissing_heart:
😚 :kissing_closed_eyes:
😳 :flushed:
😌 :relieved:
😆 :satisfied:
😁 :grin:
😉 :wink:
😜 :stuck_out_tongue_winking_eye:
😝 :stuck_out_tongue_closed_eyes:
😀 :grinning:
😗 :kissing:
😙 :kissing_smiling_eyes:
😛 :stuck_out_tongue:
😴 :sleeping:
😟 :worried:
😦 :frowning:
😧 :anguished:
😮 :open_mouth:
😬 :grimacing:
😕 :confused:
😯 :hu ...
MySQL事务与MVCC
MySQL事务与MVCC
¶事务介绍
¶事务的四大特性(ACID)
原子性(atomicity): 事务的最小工作单元,要么全成功,要么全失败。
一致性(consistency): 事务开始和结束后,数据库的完整性不会被破坏。
隔离性(isolation): 不同事务之间互不影响,四种隔离级别为RU(读未提交)、RC(读已提交)、RR(可重复读)、SERIALIZABLE (串行化)。
持久性(durability): 事务提交后,对数据的修改是永久性的,即使系统故障也不会丢失。
¶有哪些问题
脏读(dirty read):如果一个事务读到了另一个未提交事务修改过的数据。
不可重复读(non-repeatable read):如果一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事务都能查询得到最新值。
幻读(phantom read):如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来。
¶事务的隔离级别
¶读未提交(Read ...
MySQL架构介绍
MySQL架构介绍
¶Mysql逻辑架构介绍
Connectors
指的是不同语言中与SQL的交互。
Management Serveices & Utilities:
系统管理和控制工具
Connection Pool: 连接池
管理缓冲用户连接,线程处理等需要缓存的需求。
负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,
接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。
SQL Interface: SQL接口。
接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface。
Parser: 解析器。
SQL命令传递到解析器的时候会被解析器验证和解析。解析器是由Lex和YACC实现的 ...
MySQL锁机制
MySQL锁机制
¶概述
MySQL锁分类:
从对数据操作的类型(读\写)分:
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
从对数据操作的粒度分:
表锁
行锁
¶表锁(偏读)
¶特点
偏向MyISAM存储引擎,开销小,加锁快;无死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
¶读锁
【效果】
一个会话给表加了读锁,自身不能写。
一个会话给表加了读锁,自身不能读其他表。
一个会话给表加了读锁,其他会话可以读
一个会话给表加了读锁,其他会话申请写,会陷入阻塞。
¶写锁
【效果】
一个会话给表加了写锁,自身能读。
一个会话给表加了写锁,自身不能读其他表。
一个会话给表加了写锁,其他会话申请写,会陷入阻塞。
一个会话给表加了写锁,其他会话申请读,会陷入阻塞
¶总结
Myisam的读写锁调度是写优先,这也是myisam不适合做写为主表的引擎。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞
¶行锁(偏写)
¶特点
偏向InnoDB存储引擎,开销大, ...
查询截取分析
查询截取分析
¶查询优化
¶永远小表驱动大表
¶order by关键字优化group by关键字优化
ORDER BY子句,尽量使用Index方式排序,避免使用FileSort方式排序
ORDER BY满足两情况,会使用Index方式排序:
ORDER BY语句使用索引最左前列
使用where子句与Order BY子句条件列组合满足索引最左前列
尽可能在索引列上完成排序操作,遵照索引建的最佳左前缀
如果不在索引列上,filesort有两种算法:mysql就要启动双路排序和单路排序
双路排序
MySQL 4.1之前是使用双路排序,字面意思就是两次扫描磁盘,最终得到数据,读取行指针和orderby列,对他们进行排序,然后扫描己经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出
从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段。
取一批数据,要对磁盘进行了两次扫描,众所周知,Io是很耗时的,所以在mysq4.1之后,出现了第二种改进的算法,就是单路排序。
单路排序
从磁盘读取查询需要的所有列,按照order by列在 ...
索引
索引
¶SQL性能下降的原因
查询语句写的烂
索引失效
关联查询太多join(设计缺陷或不得已的需求)
服务器调优及各个参数设置(缓冲、线程数等)
…
¶常见通用的Join查询
¶SQL执行顺序:
select 查询列表 ⑦
from 表1 别名 ①
连接类型 join 表2 ③
on 连接条件 ②
where 筛选 ④
group by 分组列表 ⑤
having 筛选 ⑥
order by排序列表 ⑧
limit 起始条目索引,条目数; ⑨ 1、asc :升序,如果不写默认升序 desc:降序
¶7种SQL
1、左连接
select * from a left join b on a.id = b.id
2、右连接
select * from a right join b on a.id = b.id
3、左连接之后去除共有部分
select * from a left join b on a.id = b.id where b.id is null
4、内连接
select ...
AQS
AQS
¶学习AQS的思路
学习AQS的目的主要是想理解原理、提高技术,以及应对面试
先从应用层面理解为什么需要他如何使用它,然后再看一看我们Java代码的设计者是如何使用它的了解它的应用场景
这样之后我们再去分析它的结构,这样的话我们就学习得更加轻松了
¶为什么需要AQS ?
锁和协作类有共同点︰闸门
我们已经学过了ReentrantLock和Semaphore,有没有发现它们有共同点?很相似?
事实上,不仅是ReentrantLock和Semaphore,包括CountDownLatch、ReentrantReadWriteLock都有这样类似的“协作”(或者叫“同步”)功能,其实,它们底层都用了一个共同的基类,这就是AQS
因为上面的那些协作类,它们有很多工作都是类似的,所以如果能提取出一个工具类,那么就可以直接用,对于ReentrantLock和Semaphore而言就可以屏蔽很多细节,只关注它们自己的“业务逻辑”就可以了
¶AQS的作用
我们可以看到在锁和协作类内部几乎都有一个sync内部类,Sync类继承了AQS
AQS帮协作工具实现:
同步状态的原子性管理 ...
Future和Callable
Future和Callable
¶Runnable的缺陷
不能返回一个返回值
也不能抛出checked Exception
¶Callable接口
类似于Runnable,被其它线程执行的任务
实现call方法
有返回值
¶Future类
¶Future和Callable的关系
我们可以用Future.get来获取Callable接口返回的执行结果,还可以通过Future.isDone()来判断任务是否已经执行完了,以及取消这个任务,限时获取任务的结果等
在call()未执行完毕之前,调用get()的线程(假定此时是主线程)会被阻塞,直到call()方法返回了结果后,此时future.get()才会得到该结果,然后主线程才会切换到runnable状态
所以Future是一个存储器,它存储了call()这个任务的结果,而这个任务的执行时间是无法提前确定的,因为这完全取决于call()方法执行的情况
¶Future的常用方法
get()方法∶获取结果
get方法的行为取决于Callable任务的状态,只有以下这5种情况︰
任务正常完成:get方法会立刻返回结果
任务 ...
并发流程控制
并发流程控制
¶什么是控制并发流程?
控制并发流程的工具类,作用就是帮助我们程序员更容易得让线程之间合作
让线程之间相互配合,来满足业务逻辑
比如让线程A等待线程B执行完毕后再执行等合作策略
¶CountDownLatch倒计时门闩
¶CountDownLatch类的作用
流程︰倒数结束之前,一直处于等待状态,直到倒计时结束了,此线程才继续工作。
常用方法:
CountDownLatch(int count):仅有一个构造函数,参数count为需要倒数的数值。
await():调用await()方法的线程会被挂起,它会等待直到值为0才继续执行。
countDown():将count值减1,直到为0时,等待的线程会被唤起。
¶两个典型用法
用法一:一个线程等待多个线程都执行完毕,再继续自己的工作。
12345678910111213141516171819202122232425262728293031/** * 描述: 工厂中,质检,5个工人检查,所有人都认为通过,才通过 */public class CountDownLatchDemo1 { pu ...