1.newCachedThreadPool
核心线程数为0,最大线程数为 Integer.MAX_VALUE
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
2.newFixedThreadPool
- 核心线程数与最大线程数均为指定的nThreads
- 空闲线程的存活时间是0
- 工作队列是无界队列
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
3.newSingleThreadExecutor
- 核心线程数与最大线程数均为1
- 工作队列是无界队列
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
4.newScheduledThreadPool
- 指定核心线程数corePoolSize
- 最大线程数是Integer.MAX_VALUE
- DelayedWorkQueue:任务队列会根据任务延时时间的优先级进行执行
ScheduledExecutorService#scheduleAtFixedRate() 指的是“以固定的频率”执行,period(周期)指的是两次成功执行之间的时间
ScheduledExecutorService#scheduleAtFixedRate() 指的是“以固定的频率”执行,period(周期)指的是两次成功执行之间的时间
比如,scheduleAtFixedRate(command, 5, 2, second)
,第一次开始执行是5s后,假如执行耗时1s,那么下次开始执行是7s后,再下次开始执行是9s后
而ScheduledExecutorService#scheduleWithFixedDelay() 指的是“以固定的延时”执行,delay(延时)指的是一次执行终止和下一次执行开始之间的延迟
而ScheduledExecutorService#scheduleWithFixedDelay() 指的是“以固定的延时”执行,delay(延时)指的是一次执行终止和下一次执行开始之间的延迟
scheduleWithFixedDelay(command, 5, 2, second)
,第一次开始执行是5s后,假如执行耗时1s,执行完成时间是6s后,那么下次开始执行是8s后,再下次开始执行是11s后
数据会先写入内存buffer,然后每隔1s refresh到 os cache中,到了oscache中就可以被搜索到了,每隔5s会写入一次translog文件,所以就算机器宕机,最多会有5s的数据丢失,translog 大到一定程度,或者每隔30mins,会触发commit操作,将缓存区的数据flush到磁盘文件中
\1. 为 instance 分配内存空间;
\2. 初始化 instance;
\3. 将 instance 指向分配的内存地址
由于但是由于 JVM 具有指令重排的特性,执行顺序有可能变成 1->3->2。指令重排在单线程环境下不会出现问题,但是在多线程环境下会导致一个线程获得还没有初始化的实例。例如,线程 a 执行了 1 和 3,此时 线程 b 调用 getSingleton() 后发现 instance 不为空,因此返回 instance,但此时 instance 还未被初始化,所以就会导致空指针异常
。
一.mysql索引结构
mysql常用的两种存储引擎:innodb,mylsam
innodb和mylsam主要区别
1.innodb支持事务,支持行锁,mylsam不支持
2.MyISAM索引文件和数据文件是分离的,用mylsam建表 会生成三个文件,
.frm .MYD .MYI ,使用innodb建表只会生成两个文件 。frm和.ibd文件
索引的数据结构为B+树
B+树 的非叶子节点不存储data,只存储索引,可以放更多的索引
叶子节点包含所有的索引字段,并用指针连接
B树每个叶子节点都存储数据
MySQL索引调优
使用explain关键字进行sql的分析
1.如果索引了多列,要遵守最左前缀法则。查询从联合索引的最左前列开始并且不跳过索引、
不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
3.尽量使用覆盖索引(只访问索引的查询(索引列包含查询列)),减少select *语句
4.mysql在使用不等于(!=或者<>)的时候
is null,is not null
like以通配符开头
字符串不加单引号
无法使用索引会导致全表扫描
filesort文件排序方式
单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序
双路排序(又叫回表排序模式):是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行 ID,然后在 sort buffer 中进行排序,排序完后需要再次取回其它需要的字段
MySQL 通过比较系统变量 max_length_for_sort_data(默认1024字节) 的大小和需要查询的字段总大小来判断使用哪种排序模式。
如果 max_length_for_sort_data 比查询字段的总长度大,那么使用 单路排序模式;
如果 max_length_for_sort_data 比查询字段的总长度小,那么使用 双路排序模式。
select * from employee where name=‘zhuge’ order by position
我们先看单路排序的详细过程:
- 从索引name找到第一个满足 name = ‘zhuge’ 条件的主键 id
- 根据主键 id 取出整行,取出所有字段的值,存入 sort_buffer 中
- 从索引name找到下一个满足 name = ‘zhuge’ 条件的主键 id
- 重复步骤 2、3 直到不满足 name = ‘zhuge’
- 对 sort_buffer 中的数据按照字段 position 进行排序
- 返回结果给客户端
我们再看下双路排序的详细过程:
- 从索引 name 找到第一个满足 name = ‘zhuge’ 的主键id
- 根据主键 id 取出整行,把排序字段 position 和主键 id 这两个字段放到 sort buffer 中
- 从索引 name 取下一个满足 name = ‘zhuge’ 记录的主键 id
- 重复 3、4 直到不满足 name = ‘zhuge’
5.对 sort_buffer 中的字段 position 和主键 id 按照字段 position 进行排序
6.遍历排序好的 id 和字段 position,按照 id 的值回到原表中取出 所有字段的值返回给客户端
mysql的表关联常见有两种算法
Nested-Loop Join 算法
Block Nested-Loop Join 算法