源码

RedissonClient获取锁源码解析

安稳与你 提交于 2020-02-20 10:17:24
代码示例: public static boolean acquire(RedissonClient redisson, String lockKey, Long waitTime, Long leaseTime) {     // 实例化锁对象(此时未请求redis) RLock lock = redisson.getLock(lockKey); boolean lockResult; try { lock.lock();       // 加锁 lockResult = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS); }catch (Exception e){ lockResult = false; } if (lockResult){ log.info("======lock success <"+lockKey+">======"+Thread.currentThread().getName()); }else { log.error("======lock error <"+lockKey+">======"+Thread.currentThread().getName()); } //加锁成功 return lockResult; } 流程图: 源码分析: Redisson实例化 /***************

HashMap源码详解

帅比萌擦擦* 提交于 2020-02-20 08:47:52
概述 HashMap是基于哈希表(散列表),实现Map接口的双列集合,数据结构是“链表散列”,也就是数组+链表 ,key唯一的value可以重复,允许存储null 键null 值,元素无序。 哈希表 数组:一段连续控件存储数据,指定下标的查找,时间复杂度O(1),通过给定值查找,需要遍历数组,自已对比复杂度为O(n) 二分查找插值查找,复杂度为O(logn) 线性链表:增 删除仅处理结点,时间复杂度O(1)查找需要遍历也就是O(n) 二叉树:对一颗相对平衡的有序二叉树,对其进行插入,查找,删除,平均复杂度O(logn) 哈希表:哈希表中进行添加,删除,查找等操作,性能十分之高,不考虑哈希冲突的情况下,仅需一次定位即可完成,时间复杂度为O(1)哈希表的主干就是数组 hash冲突 如果两个不同的元素,通过哈希函数得出的实际存储地址相同怎么办?也就是说,当我们对某个元素进行哈希运算,得到一个存储地址,然后要进行插入的时候,发现已经被其他元素占用了,其实这就是所谓的哈希冲突,也叫哈希碰撞。前面我们提到过,哈希函数的设计至关重要,好的哈希函数会尽可能地保证 计算简单和散列地址分布均匀,但是,我们需要清楚的是,数组是一块连续的固定长度的内存空间,再好的哈希函数也不能保证得到的存储地址绝对不发生冲突。那么哈希冲突如何解决呢?哈希冲突的解决方案有多种:开放定址法(发生冲突

Mybatis3源码分析(3)流程走向

匆匆过客 提交于 2020-02-20 07:55:49
分析源码我们还是从编程式demo入手 我们通过建造者模式创建一个工厂类,配置文件的解析就是在这一步完成的,包括 mybatis-config.xml 和 Mapper 适配器文件。 首先进入build 进入XMLconfigBuilder–这里就是配置文件创建的地方 可以看到这里有很多解析文件的类 解析节点–这里可以看出文件只解析了一次。 解析文件还是比较简单的,基本上就是读取文件的内容然后做存储设置,我们来看看时序图 DefaultSqlSession–最主要的就是创建了一个执行器 创建回话时拿到全局配置文件的配置,并且创建了事务工厂和创建执行器。 对执行器做判断–两次判断的原因是因为怕有人把默认执行器设置为空–这里也判断了是否开启了二级缓存的– 这里注意这个额插件调用方法先把他理解为拦截器进行了一次包装 我在baseExecutor里面还看到了模板模式–把具体的增删改查的方法都交给子类去做了 先看看继承关系 看看时序图 getMapper 为什么要引入mapper对象------为了解决这种硬编码的问题 一步步走 注意这个注册器-点进去看 这里的代码就有点熟悉了吧。 jdk的动态代理 那么作为代理类一定有个规范,我们进去看 果然实现了invocationHandler 说明mapper对象是一个代理对象 为什么我们只需要mapper接口不需要去实现呢 目前来看

HashMap-treeifyBin()源码简读(JDK1.8)

拟墨画扇 提交于 2020-02-20 05:03:41
HashMap的treeifyBin()方法源码 final void treeifyBin ( Node < K , V > [ ] tab , int hash ) { //定义几个变量,n是数组长度,index是索引 int n , index ; Node < K , V > e ; //这里的tab指的是本HashMap中的数组,n为数字长度,如果数组为null或者数组长度小于64 if ( tab == null || ( n = tab . length ) < MIN_TREEIFY_CAPACITY ) //则调用resize()方法直接扩容,不转红黑树 resize ( ) ; //否则说明满足转红黑树条件,通过按位与运算取得索引index,并将该索引对应的node节点赋值给e,e不为null时 else if ( ( e = tab [ index = ( n - 1 ) & hash ] ) != null ) { //定义几个变量,hd代表头节点,tl代表尾节点 TreeNode < K , V > hd = null , tl = null ; do { //先把e节点转成TreeNode类型,并赋值给p TreeNode < K , V > p = replacementTreeNode ( e , null ) ; //如果尾节点tl为空

15.Spark源码分析

无人久伴 提交于 2020-02-20 03:15:55
Spark源码分析 各个组件介绍 后面补充。。。。 StandAlone模式 在StandAlone模式的start-all的shell启动脚本下,在当前机器执行了JAVA_HOME/bin/java -cp ....Master和在配置的slave的机器中执行 JAVA_HOME/bin/java -cp ....Worker.这两种进程在启动后通过netty进行rpc通信。 Master的启动 首先创建一个RpcEnv对象,负责管理所有通信逻辑,核心代码为 val rpcEnv: RpcEnv = RpcEnv.create(SYSTEM_NAME, host, port, conf, securityMgr) ,创建后启动NettyRpcEnv Utils.startServiceOnPort(config.port, startNettyRpcEnv, sparkConf, config.name)._1 接着创建一个Master的EndPoint对象 val masterEndpoint: RpcEndpointRef = rpcEnv.setupEndpoint(ENDPOINT_NAME,new Master(rpcEnv, rpcEnv.address, webUiPort, securityMgr, conf)) 该EndPoint对象有 constructor

Linux笔记—服务管理

妖精的绣舞 提交于 2020-02-20 03:04:03
文章目录 服务简介与分类 服务的分类 启动与自启动 查询已安装的服务 RPM包安装的服务 源码包安装的服务 安装服务的区别——安装位置的不同 RPM包安装服务的管理 安装的通用默认位置 独立服务的管理 启动方法 自启动方法 基于xinetd服务的管理 源码包服务的管理 启动方法 自启动方法 让源码包服务被服务管理命令service识别启动 让源码包服务能被chkconfig与ntsysv命令管理自启动 服务简介与分类 服务的分类 Linux服务 RPM包默认安装的服务 独立的服务 基于xinetd的服务 源码包安装的服务 启动与自启动 服务启动:就是在当前系统中让服务运行,并提供功能 服务自启动:自启动是指让服务在系统开机或重新启动之后,随着系统的启动而自动启动服务 查询已安装的服务 RPM包安装的服务 chkconfig --list #查看服务自启动状态,可以看到所有RPM包安装的服务 源码包安装的服务 查看服务安装位置,一般是/usr/local/下 安装服务的区别——安装位置的不同 RPM包安装在默认位置中 源码包安装在指定位置中,一般是/usr/local/ RPM包安装服务的管理 安装的通用默认位置 文件路径 文件内容 /etc/init.d/ 独立服务的启动脚本位置 /etc/sysconfig/ 初始化环境配置文件位置 /etc/ 配置文件位置 /etc

tomcat-embeded-core源码编译

≯℡__Kan透↙ 提交于 2020-02-19 14:27:41
使用spring-boot创建web工程时,默认采用embeded tomcat作为容器,实际使用过程中,可能会需要对其中的某些功能做微调,而tomcat又没有给出预留配 ,这时就需要对tomcat-embed-core源码进行编译了,下面说下具体的步骤 创建工程 在eclipse中创建tomcat-embed-core的maven工程 通过maven下载一个自己需要编译的tomcat-embed-core版本对应的source包(以8.5.31为例) 解压tomcat-embed-core对应的source包 将source包中javax和org两个包copy到刚创建的maven工程的src/main/java目录下 将source包中的META-INF放到src/main/resources目录下 编辑pom文件,追加依赖包、编译内容、以及发布的默认maven仓库 <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional

Android源码编译App Android.mk出现无法import aidl AIDL的接口找不到cannot import

扶醉桌前 提交于 2020-02-19 10:39:05
Android.mk添加以下内容即可 LOCAL_SRC_FILES := $(call all-java-files-under,app/src/main/java) LOCAL_SRC_FILES += $(call all-Iaidl-files-under,app/src/main/aidl/android/os) LOCAL_SRC_FILES += $(call all-Iaidl-files-under,app/src/main/aidl) LOCAL_SRC_FILES += $(call all-Iaidl-files-under,app) LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/app/src/main/aidl/android/os LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/app/src/main/aidl 来源: CSDN 作者: 镇上村树 链接: https://blog.csdn.net/realDonaldTrump/article/details/104374430

Python原来这么好学-1.2节: 在Linux中安装python

爱⌒轻易说出口 提交于 2020-02-19 00:16:33
这是一本教同学们彻底学通Python的高质量学习教程,认真地学习每一章节的内容,每天只需学好一节,帮助你成为一名卓越的Python程序员: 本教程面向的是零编程基础的同学,非科班人士,以及有一定编程水平的中高级程序员。 1.2.1 Linux系统分类 在python官网中同时提供了针对Linux系统的安装包,在Linux系统的主要发行版中,按其软件包格式来进行划分,可分为Deb系以及RPM系操作系统。 Linux系统与Windows系统有一个很重要的区别,Linux系统完全免费,开放源代码,所 以Linux系统才会有这么多分支。 Deb系比较有代表性的是Ubuntu、Debian。Ubuntu主要用来做桌面操作系统,Debian主要用来做服务器操作系统。 RPM系主要用来做服务器操作系统,比较有代表性的是Redhat、CentOS: 对Linux系统感兴趣的初学者,可以通过Vmware或者VirtulBox等工具,在windows系统中创建一个虚拟机, 然后下载Linux系统的镜像文件,在虚拟机中运行Linux系统。 1.2.2 在Linux系统中安装python 在本节的教程中,笔者以RPM系中的CentOS系统为例,来演示如何在Linux中安装python。 请读者按照以下步骤来进行操作: (1) 下载python源码包 打开python的源码包下载页面: https:/

CopyOnWriteArrayList 源码解析和设计思路

百般思念 提交于 2020-02-18 20:04:21
引导语 在 ArrayList 的类注释上,JDK 就提醒了我们,如果要把 ArrayList 作为共享变量的话,是线程不安全的,推荐我们自己加锁或者使用 Collections.synchronizedList 方法,其实 JDK 还提供了另外一种线程安全的 List,叫做 CopyOnWriteArrayList,这个 List 具有以下特征: 线程安全的,多线程环境下可以直接使用,无需加锁; 通过锁 + 数组拷贝 + volatile 关键字保证了线程安全; 每次数组操作,都会把数组拷贝一份出来,在新数组上进行操作,操作成功之后再赋值回去。 1 整体架构 从整体架构上来说,CopyOnWriteArrayList 数据结构和 ArrayList 是一致的,底层是个数组,只不过 CopyOnWriteArrayList 在对数组进行操作的时候,基本会分四步走: 加锁; 从原数组中拷贝出新数组; 在新数组上进行操作,并把新数组赋值给数组容器; 解锁。 除了加锁之外,CopyOnWriteArrayList 的底层数组还被 volatile 关键字修饰,意思是一旦数组被修改,其它线程立马能够感知到,代码如下: private transient volatile Object[] array; 整体上来说,CopyOnWriteArrayList 就是利用锁 + 数组拷贝 +