
【Java】
文章平均质量分 85
理想主义的许佳佳
一位理想主义的程序员,祝你健康幸福。
展开
-
Rxjava 源码解析(三) - Schedulers默认线程池
概述前文已经分析过rxjava中我们常见用法的一些源码,还没有了解的读者推荐看下:Rxjava 源码解析(一) - subscribe源码Rxjava 源码解析(二) - 线程切换源码本文将分析下rxjava线程池相关的源码。本文的内容大概有以下:Scheduers.io()源码线程工厂RxThreadFactory源码线程池CachedWorkerPool源码Worker的创建与调用Scheduers.io()源码rxjava内置的线程池除了io,还有newThead,singl原创 2021-08-28 08:47:18 · 1621 阅读 · 0 评论 -
Rxjava 源码解析(一) - subscribe源码
概述rxjava的应用还是较为广泛的,在实际项目中经常与MVP一起使用,可以使代码的可读性更高。在较为复杂的一些场景下,也可以使代码更加的简洁。本文将会是对rxjava源码的探索,适合已经对rxjava的使用有一定经验的读者。对MVP有兴趣的读者可以看下笔者的前文:MVC、MVP、MVVM小记同步Demo主要逻辑如下:Observable调用create()创建 ObservableCreateObservableCreate调用map,返回ObservableMapObservab原创 2021-08-19 08:13:57 · 902 阅读 · 0 评论 -
Rxjava 源码解析(二) - 线程切换源码
概述前文已经讲了rxjava 简单subscribe的源码,有兴趣的读者可以看下。Rxjava 源码解析(一) - subscribe源码本文将基于前文的分析,继续讲下rxjava中断线程切换。Demo主要逻辑如下:Observable调用create()创建 ObservableCreateObservableCreate调用map,返回ObservableMapObservableMap调用subscribeOn,返回ObservableSubscribeOn返回Observable原创 2021-08-20 09:15:54 · 439 阅读 · 0 评论 -
迁移或备份csdn文章小结
概述一直想要备份下自己优快云的文章,目前光原创的就有300多篇,完全手动备份太耗时间,于是准备写代码来实现。大概思考了下,备份差不多需要以下几部分:备份文章的markdown文件备份所有文章中的图片(毕竟很多都是亲手画的,都是心血)替换所有markdown文件中图片的url最终效果最终备份了300多篇文章和400多张图片,总共700多个文件,如下图:下载所有图片和替换所有url的总耗时 2分29秒,如下图:备份markdown这个部分直接在github上找到了现有的项目,相关项原创 2021-03-13 19:25:35 · 478 阅读 · 2 评论 -
序列化小结
为什么要序列化wiki的描述如下:序列化在计算机科学的资料处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。笔者个人理解如下:序列化:“把当前环境的数据结构 转化成一种 可存储 或者 可传输的形式” 的过程。反序列化:”这种可传输或者可存储的形式 还原成 当前环境的数据结构“的过程。此处为了便于读者理解举个例子:现在有一个 Student类,有name,age等参数。需求一原创 2021-02-09 06:29:49 · 318 阅读 · 0 评论 -
Java8 JVM内存结构变了,永久代到元空间
JVM内存结构的细化为了更细化的讲解,我们将该图进行进一步的优化调整。针对java7及以前版本的细化。看出变化了吗?堆和方法区连在了一起,但这并不能说堆和方法区是一起的,它们在逻辑上依旧是分开的。但在物理上来说,它们又是连续的一块内存。也就是说,方法区和前面讲到的Eden和老年代是连续的。在继续进行下去之前,我们先来理解两个概念:规范和实现。规范和实现针对Java虚拟机的实现有专门的《Java虚拟机规范》,在遵守规范的前提下,不同的厂商会对虚拟机进行不同的实现。 就好比开发的过程中定义了接口转载 2020-11-13 21:28:21 · 577 阅读 · 0 评论 -
一篇文章理解进程、线程、协程
概述笔者之前已经对进程和线程有过了一定的探索,有兴趣的读者可以了解下:进程和线程的区别(Linux)近期笔者又接触到了协程,顺便也想尝试用一种更加通俗易懂的方式讲下这几个概念。期望能对有需要的读者有所帮助,如有理解不对的地方欢迎评论指出。为什么要有多进程?多进程目的:提高cpu的使用率例子:一个用户现在既想使用打印机,又想玩游戏。假设只有一个进程(先不谈多线程)从操作系统的层面看,我们使用打印机的步骤有如下:使用CPU执行程序,去硬盘读取需要打印的文件,然后CPU会长时间的等待原创 2020-11-01 08:17:42 · 1281 阅读 · 2 评论 -
线程池解析(四)——submit源码解析(Runnable、Callable、Future、FutureTask)
概述线程池的submit也是常用的方法之一,它有很多个重载,涉及到了很多个类。本文将探索submit方法以及相关的各个类。submit源码我们看下ThreadPoolExecutor中sumit相关的源码。 protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) { return new FutureTask<T>(runnable, value);原创 2020-09-12 10:14:58 · 1987 阅读 · 0 评论 -
线程池解析(三)——Worker源码解析
概述在ThreadPoolExecutor中以Worker为单位对工作线程进行管理。那么Worker具体是做了什么呢?本文将围绕这个话题展开。Worker源码 private final class Worker extends AbstractQueuedSynchronizer implements Runnable { /** * This class will never be serialized, but we prov原创 2020-09-12 10:13:20 · 955 阅读 · 0 评论 -
线程池解析(二)——execute、addWorker源码解析
概述线程池使用execute执行任务,在创建线程池后,开发者只要调用这个方法就能愉快的使用线程池了。本文将探索下其内部实现逻辑。execute源码 public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountO原创 2020-09-12 10:10:30 · 1150 阅读 · 1 评论 -
线程池解析(一)——概念总结
线程池作用节省资源。使用线程池可以避免每次异步操作都去创建一个线程。提高响应速度。由于线程池本身会创建一些线程,能够节省创建线程池的时间。更好的管理线程。线程池可以控制其线程的创建停止,存活个数等等。不仅能够保证系统的稳定运行,同时也可以更加方便的性能调优。核心参数corePoolSize核心线程数。线程池中使用会保留的对象,maximumPoolSize线程池上限。线程池中线程的最大个数keepAliveTime线程维持时间。corePoolSize<当前线程个数&l原创 2020-08-29 10:24:58 · 435 阅读 · 0 评论 -
Gson 根据条件解析
概述Gson在实际使用中,可能出现需要根据其中的某些参数来决定另外的参数的类型的情况,如下数据结构:public class DataOne { public int type;//0代表data是DataTwo 1代表data是DataThree public Object data;//类型是DataTwo 或者DataThree}public class DataThree { public int height; public int width;}public c原创 2020-08-21 07:32:19 · 512 阅读 · 0 评论 -
一篇文章理解 同步异步、阻塞非阻塞
前述同步异步,阻塞非阻塞是一些非常常见的概念,但是对于开发者来说往往是用到了很难说清楚。笔者专门整理了下这方面的概念,作此文以记之。这部分内容可能存在一些争议,如有不同意见欢迎评论交流。概念个人理解同步异步与阻塞非阻塞最好的区分是从描述对象上:同步异步:用于描述任务、事件或者行为。阻塞非阻塞:用于描述线程或者进程是否会被挂起。同步一个任务调起另一个任务的时候,会去等待其任务返回结果(或执行结束),然后再继续执行。如下两图都是同步操作:在Task A调用Task B后,Task原创 2020-06-06 18:35:51 · 1822 阅读 · 0 评论 -
Java与Android的类加载器
双亲委派模型在加载一个字节码文件时,会询问当前的classLoader是否已经加载过此字节码文件。如果加载过,则直接返回,不再重复加载。如果没有加载过,则会询问它的Parent是否已经加载过此字节码文件,同样的,如果已经加载过,就直接返回parent加载过的字节码文件,而如果整个继承线路上的classLoader都没有加载过,才由child类加载器(即,当前的子classLoader)执行类的加载工作。特点显然,如果一个类被classLoader继承线路上的任意一个加载过,那么在以后整个系统的生命周期转载 2020-05-16 15:46:21 · 384 阅读 · 0 评论 -
【StudyRouter】路由的自动注册
StudyRouter项目地址:https://github.com/Double2hao/StudyRouter此项目通过使用动态编译、注解解释器等技术,用最简单的方式实现了路由的自动注册。如对这方面知识有兴趣的朋友可以看看。实现通过注解解释器生成辅助类通过Transform出辅助类和要注入代码的位置。在相应的位置调用辅助类的相关代码,实现自动注册。涉及知识点列表笔者...原创 2020-04-19 08:18:27 · 541 阅读 · 0 评论 -
动态编译 java ASM入门
概述ASM 是java字节码操作框架。由于ASM性能好的原因,所以在动态编译上往往比Javassist上使用的更加广泛。之前已经写过了Javassist实现动态编译的demo,对动态编译不了解的读者可以看下:动态编译入门(gradle Transform Demo)本文在前面demo的基础上,将Javassist的实现改为了ASM。因此对于gradle 插件等重复的点就不多加描述了,本文...原创 2020-04-05 10:36:50 · 1538 阅读 · 0 评论 -
完全理解 java操作数栈和局部变量表
概要近期学习到字节码操控框架ASM,其中对方法的定义需要设置最大操作数栈和局部变量表。于是,自己又复习了一遍java栈帧的概念。如果对栈帧概念还不了解的读者推荐看下此文章:详细解析Java虚拟机的栈帧结构例子综述本文将会通过诸多字节码的例子,来具体分析在不同情况下的方法的操作数栈和局部变量表。本文的分析主要基于javac和javap的使用:首先用javac生成java文件编译...原创 2020-04-05 09:30:43 · 2253 阅读 · 1 评论 -
编译时注解 AbstractProcessor (Activity路由Demo)
概述前一篇文章已经整理过注解的一些概念,也是附上了运行时注解的Demo,如果对注解概念不是很熟的读者建议先看下前一篇文章:android 注解入门(Acitivity路由demo)此篇文章主要讲一下编译时注解的使用,同时也是以”Activity路由“的Demo为例子。本篇的Demo主要是演示了使用编译时注解来创建文件的功能。主要模块anotationrouter:创建注解pro...原创 2020-03-22 16:26:04 · 2727 阅读 · 1 评论 -
android 注解入门(Acitivity路由demo)
参考《Java编程思想》概述近期接触了路由和模块间通信的内容,发现Java注解非常常用。避免后面看各源码被其阻塞,大致了解了下,作此文记录之。注解类型@Target@Retention@Documented@Inherited@Target用于描述注解的使用范围,可能的ElementType参数如下:CONSTRUCTOR:用于描述构造器FIELD:用于描述域L...原创 2020-03-14 16:50:55 · 778 阅读 · 0 评论 -
Java内存模型和Volatile
Java内存模型为了提高代码的执行速度,Java内存模型中有两个优化方案:1、每个Java线程会有一个工作内存,工作内存中的内容会在一定条件下同步到主内存。为什么工作内存可以提高代码的执行速度?从硬件上来看CPU的速度>内存的速度。每次CPU去内存中读写数据的时候,CPU一般都是阻塞的,需要等内存执行完毕后CPU才会继续执行。Java工作内存可以认为是CPU高速缓存,那么就能避...原创 2019-06-29 18:20:53 · 475 阅读 · 0 评论 -
Java内存区域
概要近期看知乎脉脉上其他人对Java知识的讲解,发现自己居然连Java内存区域的各种内容都记不太清了。遍历博客文章的时候发现也没有这方面的记载,好像都记录在毕业前面试小本子上了。之后可能会开始捡起一写Java基础知识,也是温故而知新吧。本文参考《深入理解Java虚拟机》Java内存区域图图片摘自《深入理解Java虚拟机》Java内存主要区域:程序计数器虚拟机栈本地方法栈...原创 2019-06-29 15:50:19 · 348 阅读 · 0 评论 -
ThreadLocal与ThreadLocalMap源码解析
文章个人见解较多,如有问题欢迎指出。使用场景一般来说,某些数据是以线程为作用域并且不同线程具有不同的数据的数据副本的时候,就可以考虑采用ThreadLocal。 比如Looper 内部就是通过ThreadLocal来保证不同线程中有不同的唯一副本的,从而实现了我们现在经常使用的android消息机制。 对于android消息机制不了解,并且好奇的同学可以先看一下笔者的...原创 2017-07-26 10:29:26 · 1695 阅读 · 0 评论 -
HashMap源码分析
前提概要:HashMap算是Map的子类中用的最多的了,其相关的类也有很多,比如LinkedHashMap、HashMap、HashTable、ConcurrentHashMap。而HashMap在其中也扮演着一个很重要的角色,本文主要分析HashMap的源码,了解完后,其他的也自然触类旁通了。概述HashMap本身是数组+链表的存储结构(JDK1.8加上了红黑树部分,本篇文章不提...原创 2017-06-19 16:43:56 · 1577 阅读 · 5 评论 -
netty 长连接 demo
概要近期接触netty长连接方面,实现简单demo记录,主要实现以下内容:使用HashMap存储Channel,保证需要的时候可以根据key获取到。被HashMap存储的长连接实现心跳机制。demo中是以id为key存储在HashMap中,解析内容用到了Gson。为了让demo更容易理解,没有实现粘包分包的逻辑,一旦发生会有问题。对粘包和分包有兴趣的可以看下笔者的另一篇文章:So...原创 2019-07-20 10:11:33 · 1068 阅读 · 0 评论 -
ReentrantLock和AQS 源码解析
概要ReentrantLock是一种经常会被用来与Synchronized比较的一种同步机制,其在Java中的应用也十分广泛,比如最常见的BlockingQueue就是使用了ReentrantLock来实现的同步机制。个人认为ReentrantLock和Synchronized的区别主要有以下三点:ReentrantLock等待可中中断ReentrantLock可以实现公平锁Reen...原创 2019-08-21 22:09:04 · 552 阅读 · 0 评论 -
netty write 和flush 源码解析
本文参考:https://www.jianshu.com/p/1ad424c53e80概要netty中每次write之后都需要flush才能将消息发送出去,代码如下。笔者很好奇为什么一定要分成write和flush两个方法——既然每次都需要调用flush,直接由框架自动去调用flush不就好了吗?于是就去看了源码,写此文记之。public void channelRead(Chann...原创 2019-07-13 15:17:24 · 2728 阅读 · 0 评论 -
netty ByteBuff 详解
本文参考:https://segmentfault.com/a/1190000015104849概要netty的ByteBuff是用来替代nio的ByteBuffer的,与nio的ByteBuffer相比有诸多优势,主要有以下几点:扩容问题ByteBuffer长度固定,分多了会浪费内存,分少了会数组越界。如果发现存储的数据大于ByteBuffer的长度,那么就需要创建一个新的Byt...原创 2019-07-13 12:09:14 · 2079 阅读 · 1 评论 -
一个例子理解依赖注入
前言之前已经记录过一篇文章解释依赖注入,现在看来有点过于理论化,于是写了一个demo解释下什么是依赖注入,也是在实际开发中依赖注入的使用场景。对依赖注入还完全不理解的可以看一下上一篇文章:依赖注入 简介场景假设目前你正在开发公司的一个框架,为了保证线上代码的安全,你需要引入你们公司的“线上开关”的模块,这样如果发现你的框架有问题,可以及时用线上开关关闭部分功能,而不至于在下个版本发布前...原创 2019-04-13 15:00:03 · 1860 阅读 · 0 评论 -
JAVA 串的处理(简单的string与stringbuffer的使用)
串的处理在实际的开发工作中,对字符串的处理是最常见的编程任务。本题目即是要求程序对用户输入的串进行处理。具体的规则如下:1、 把每个单词的首字母变为大写。2、 把数字与字母之间用下划线字符(_)分开,使得更清晰3、 把单词中间有多个空格的调整为1个空格。例如:用户输入:you and me whatcpp2005program则程序输出:You A原创 2015-12-16 11:54:55 · 1139 阅读 · 0 评论 -
Java Object 之hashCode
官方参考:int hashCode () Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap.The general contract of hashCode is:Whenever it翻译 2017-03-23 16:28:20 · 901 阅读 · 1 评论 -
什么是AOP(面向切片编程)
本文参考https://juejin.im/post/591d8c8ba22b9d00585007ddAOP wiki 解释In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separatio...原创 2019-03-02 16:26:53 · 3687 阅读 · 0 评论 -
Java Synchronized 锁升级简介
锁升级顺序偏向锁轻量级锁自旋锁重量级锁偏向锁如果一个线程获得了锁,再次请求的时候就不需要再去获取锁。如果发现有其他线程来获取这个锁,就升级为轻量级锁。理论基础:在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,因此为了减少同一线程获取锁的代价而引入偏向锁。轻量级锁通过使用CAS来获取锁,如果CAS失败就升级为自旋锁。相关链接:JAVA轻量级锁简介理...原创 2019-01-26 10:59:59 · 957 阅读 · 0 评论 -
依赖注入 简介
原文地址: https://www.jianshu.com/p/bf0c9f23381a依赖注入简介依赖注入是一个很常用的词。Java新手常会写出如下的代码,直接在写一个类的时候让它自己初始化自己。但是这不是一个好办法。一个类的状态应该由创建它的类决定,不能由自己决定自己。因此更好的办法是交给构造方法来初始化。public class User { private long id...转载 2019-01-12 14:41:22 · 799 阅读 · 0 评论 -
Java 模块化(gradle)
组件化什么是组件化,直接看下面两张图。上面是非组件化的项目,下面是组件化的项目。非组件化的问题如果项目本身有多个互相不影响的模块,甚至有多人分开负责各个模块的开发时,非组件化项目的弊端就会暴露出来,主要是有下面几个:1、依赖难以管理,不同的模块依赖不同的库,甚至是同一个库的不同版本。2、各个模块单独打包麻烦。3、增加额外开发成本,开发本身可能只需要开发一个模块,但是由于代码写在一...原创 2019-01-12 11:45:01 · 3016 阅读 · 2 评论 -
JAVA轻量级锁简介
概念在某些场景下,去获取对象锁的时候使用CAS的方式,而不是阻塞。轻量级锁能够提升程序同步性能的一句是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。在 Java Object头文件中,有一个“Mark Word”对象,它是实现轻量级锁的关键。Mark Word的数据结构非固定,根据不同的状态会有不同的结构。比如在32位的HotSpot虚拟机中对象未被锁定的状态...原创 2018-10-20 17:39:47 · 2793 阅读 · 2 评论 -
Java Timer源码解析(定时器源码解析)
Timer概述Timer顾名思义就是定时器,用于处理一些需要延时处理的任务,延时时间可能是1s,也可能是5天。一般使用方式如下: TimerTask task = new TimerTask() { @Override public void run() { Log.d("test", "timer...原创 2018-10-20 14:29:18 · 1359 阅读 · 0 评论 -
CountDownLatch 概述和源码分析
概述源码中对这个类的描述如下: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 意思大概是: 它是一个线程同步的助手,能够让一个或者多个线程在一组操作完成之前等...原创 2018-09-01 16:31:49 · 389 阅读 · 0 评论 -
由浅入深完全理解Java动态代理
前言看Retrofit源码的时候涉及到了Java动态代理,这个知识点之前在学习Java反射的时候就碰到过,不过也仅仅是停留在理论的学习。终于在Retrofit源码的时候看到了实际的使用,也是格外兴奋,正好以此为契机,把Java动态代理这一块整理一下。 本文也是尽量由浅入深的讲,过多理论知识也不多加阐述。 本文参考 https://www.zhihu.com/question/2...原创 2018-05-28 16:18:58 · 3208 阅读 · 0 评论 -
分代收集算法详解
此篇文章较多借鉴《深入理解Java虚拟机》前提概要这篇文章算是对前一篇文章的一个补充,主要地讲一下涉及知识点较多的分代收集算法。如果对Java垃圾回收算法还不是很了解的读者可以先看上一篇文章:Java垃圾回收算法。分代收集概念根据对象的存活周期不同将内存划分为新生代和老年代,存活周期短的为新生代,存活周期长的为老年代。这样就可以根据每块内存的特点采用最适当的收集算法。 新生代的中每次垃圾收集中原创 2017-09-24 09:14:51 · 2630 阅读 · 1 评论 -
Java垃圾回收算法
此篇文章主要借鉴《深入理解Java虚拟机》和《Thinking in Java》前提概要Java垃圾回收机制主要有两个方面,一是垃圾回收算法,二是垃圾回收器。此篇文章主要介绍垃圾回收算法。主要的垃圾回收算法如下: 1、引用计数算法 2、标记-清扫算法 3、复制算法 4、标记-整理算法 5、分代收集算法查找可存活对象的方法除了引用计数算法外,其他的算法都需要查找可存活的对象,其方式主要如下原创 2017-07-16 12:35:23 · 1477 阅读 · 4 评论