生产-消费模型之虚假唤醒

1 何为虚假唤醒 当线程从等待状态中被唤醒时,只是发现未满足其正在等待的条件时,就会发生虚假唤醒。 之所以称其为虚假的,是因为该线程似乎无缘无故被唤醒。 虚假唤醒不会无缘无故发生,通常是因为在发起唤醒号和等待线程最终运行之间的临界时间内,线程不再满足竞态条件。 2 java中的例子 public class SpuriousWakeupRWLock { private static final CustomQueue CUSTOM_LIST = new CustomQueue(); public static void main(String[] args) throws Exception { for (int i = 0; i < 8; i++) { Thread consumer = new Thread(() -> { try { CUSTOM_LIST.

Spring实例化bean之源码分析

1 实例化bean的主流程 这张图是整体的bean的实例化的流程,我之前关于Spring的生命周期的加载bean和实例化bean的整体过程已有博文,可以 查看文章:Spring之Bean加载-解析-生命周期 调试入口 本文中的Spring源码基于3.2.x版本,为最精简的Spring源码,选取Spring自带的测试用例进行debug调试, 本文只关注单例对象的实例化bean中各组件的源码分析, 入口如下: @Test public void testConfigLocationPattern() { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(CONTEXT_WILDCARD); assertTrue(ctx.

MySQL中的page页详解

1 InnoDB中的存储结构 从InnoDB存储引擎的逻辑结构看,所有数据都被逻辑地存放在一个空间内,称为表空间(tablespace),而表空间由段(sengment)、区(extent)、页(page)组成。 在一些文档中extend又称块(block)。 1.1 表空间(table space) 表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间等。 在 InnoDB 中存在两种表空间的类型:共享表空间和独立表空间。如果是共享表空间就意味着多张表共用一个表空间。如果是独立表空间,就意味着每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间可以在不同的数据库之间进行迁移。可通过命令 mysql > show variables like 'innodb_file_per_table'; 查看当前系统启用的表空间类型。目前最新版本已经默认启用独立表空间。

实际项目运用之Filter模式(过滤器模式)

1 模式简介 1.1 定义 过滤器模式(Filter)也叫条件模式(Criteria),这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。当我们想要选择满足一个或多个条件的对象子集时,此设计模式非常有用。它属于结构模式。 1.2 优点 它提供了一种根据特定条件过滤对象的方法 我们可以随时添加新过滤器,而不会影响客户端的代码 我们可以在程序执行期间动态选择过滤器 1.3 过滤器设计 角色

实际项目运用之State模式(状态模式)

1 模式简介 定义: 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。这个模式将状态封装成独立的类,并将动作委托到代表当前状态的类的对象 状态模式的优点: >封装了转换规则 枚举可能的状态,在枚举状态之前需要确定状态种类 将所有与某个状态有关的行为放到一个类中,可方便增加新的状态 允许状态转换逻辑与状态对象合成一体,而非复杂条件语句块 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数 状态模式的缺点: >增加系统类和对象的个数 结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱 对”开闭原则”的支持不太好,增加新状态类需在状态类上增加行为方法

数据结构之BTree和B+Tree(多路平衡查找树 )

1 背景 B-Tree是为磁盘等外存储设备设计的一种平衡查找树。因此在讲B-Tree之前先了解下磁盘的相关知识。系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。 InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB存储引擎中默认每个页的大小为16KB,可通过参数innodb_page_size将页的大小设置为4K、8K、16K,在MySQL中可通过如下命令查看页的大小: mysql> show variables like 'innodb_page_size'; 而系统一个磁盘块的存储空间往往没有这么大,因此InnoDB每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小16KB。InnoDB在把磁盘数据读入到磁盘时会以页为基本单位,在查询数据时如果一个页中的每条数据都能有助于定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率。 2 定义与特性 B-Tree B-Tree结构的数据可以让系统高效的找到数据所在的磁盘块。为了描述B-Tree,首先定义一条记录为一个二元组[key, data] ,key为记录的键值(关键字),对应表中的主键值,data为一行记录中除主键外的数据。对于不同的记录,key值互不相同。

分布式全局序列ID方案之Redis优化方案

1 Redis的Flicker方案 利用redis的lua脚本功能,在每个节点上通过lua脚本生成唯一ID,生成的ID为64位,具体如下: 使用41 bit来存放时间,精确到毫秒,可以使用到2039年 使用12 bit来存放逻辑分片ID,最大分片ID是4095 使用10 bit来存放自增长ID,则每个节点,每毫秒最多可生成1024个ID 比如GTM时间 2018年6月24日11点23分 ,它的距1970年的毫秒数是 1529810591000,假定分片ID是60,自增长序列是20,则生成的ID是: 6416490681073670164 = 1529810591000 << 22 | 60 << 10 | 20 redis提供了TIME命令,取得redis服务器的秒值和微秒值 毫秒值获取命令:EVAL "local current = redis.

分布式全局序列ID方案之Flicker优化方案

1 Flicker的解决方案 MySQL中id自增的特性,可以借此来生成全局的序列号,Flicker在解决全局ID生成方案里就采用了MySQL自增长ID的机制(auto_increment + replace into + MyISAM)。一个生成64位ID方案具体就是这样的: 先创建单独的数据库,然后创建一个表: CREATE TABLE borrow_order ( id bigint(20) unsigned NOT NULL auto_increment, stub char(1) NOT NULL default '', PRIMARY KEY (id), UNIQUE KEY stub (stub) ) ENGINE=MyISAM 当我们插入记录后,执行SELECT * from borrow_order ,查询结果就是这样的: