- 博客(26)
- 收藏
- 关注
原创 【Java】AQS底层实现
1、AQS内部实现AQS是依赖内部的同步队列实现,也就是FIFO双向队列,如果当前线程竞争锁失败,那么AQS会把当前线程以及等待状态封装成一个Node节点加入到同步队列中,同时阻塞该线程,当同步状态释放时,会把首节点唤醒,使其再次尝试获取同步状态。AQS队列内部维护的是一个双向链表,这种结构每个数据都有两个指针,分别指向直接的的前驱节点和后继节点,当线程抢占锁失败时候,会封装成Node加入到AQS中去。在同步队列中,一个节点表示一个线程,他保存这线程的引用ThreadId,状态(watiStatus)
2020-12-28 21:34:25
437
原创 【Java】AQS基本概念
什么是AQSAQS队列线程等待队列,一个FIFO的双向队列,队列元素的类型为Node,Node中的thread变量用来存放进入AQS队列里面的线程,waitStatus记录当前线程等待状态。AQS中维护了一个队列,获取锁失败(非tryLock())的线程都将进入这个队列中排队,等待锁释放后唤醒下一个排队的线程(互斥锁模式下)。共享资源状态AQS中维持了一个单一的状态信息state,可以通过getState、setState、compareAndSetState函数修改其值Condition队列A
2020-12-28 19:47:56
190
原创 【Java】并发-锁
高并发的解决方案volatile、synchronized、Lock、AtomicIntegerVolatilevolatile是一种稍弱的同步机制,在访问volatile变量时不会执行加锁操作,也就不会执行线程阻塞。他实现的是变量的可见性与一致性,但是他的原子性是保证不了。读取Volatile可以使用Unsafe.getObjectVolatile()获取,保证一致性。synchronized(悲观锁)锁的对象public synchronized void method()synchron
2020-12-17 15:35:31
211
原创 【Java】ThreadLocal
ThreadLocal1、每个Thread维护着一个ThreadLocalMap的引用2、ThreadLocalMap是ThreadLocal的内部类,用Entry来进行存储3、ThreadLocal创建的副本是存储在自己的threadLocals中的,也就是自己的ThreadLocalMap。4、ThreadLocalMap的键值为ThreadLocal对象,而且可以有多个threadLocal变量,因此保存在map中5、在进行get之前,必须先set,否则会报空指针异常,当然也可以初始化一个,
2020-12-15 14:42:31
65
原创 【Java】线程池原理
问题1、线程池的线程是如何做到复用的?2、线程池是如何做到高效并发的?3、线程池怎么处理线程共用参数?3、从线程池的设计中,我们能学到什么?源码1、ThreadPoolExecutor核心实现类是ThreadPoolExecutor,先看这个类的第一个成员变量ctl,AtomicInteger这个类可以通过CAS达到无锁并发,效率比较高,这个变量有双重身份,它的高三位表示线程池的状态,低29位表示线程池中现有的线程数,用最少的变量来减少锁竞争,提高并发效率。2、execute/submit
2020-12-15 14:13:05
127
原创 【Java】线程池
什么是线程池一个线程池包括以下四个基本组成部分:1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。常见线程池不建议使用 E
2020-12-11 15:53:53
45
原创 【Java】Thread
启动线程的三种方式Thread第一种,通过继承Thread类创建线程类1、定义一个类继承Thread类,并重写Thread类的run()方法,run()方法的方法体就是线程要完成的任务,因此把run()称为线程的执行体;2、创建该类的实例对象,即创建了线程对象;3、调用线程对象的start()方法来启动线程;Runnable这种方式创建并启动多线程的步骤如下:1、定义一个类实现Runnable接口;2、创建该类的实例对象obj;3、将obj作为构造器参数传入Thread类实例对象,这个对
2020-12-10 15:24:09
77
原创 【Java】ConcurrentHashMap线程安全技巧
线程安全主要有几个方面:1、初始化数据;2、put数据;3、get数据;4、扩容;5、统计容器大小1、数据结构上Node里面的value和next都是volatile,transient volatile Node<K,V>[] table,保证线程间数据的可见性;2、读取某一个节点用的是U.getObjectVolatile(),保证数据最新;3、减小了锁的颗粒度,对链表头进行加锁;4、用到了ForwardingNode标识位,实现了get的线程安全;5、对Node中的ha
2020-12-08 14:35:50
142
原创 【Java】ConcurrentHashMap
ConcurrentHashMapConcurrentHashMap实现原理保证线程安全的方案:JDK1.7:ReenTrantLock+Segment+HashEntryJDK1.8:Synchronized+CAS+HashEntry+红黑树JDK1.7:在JDK1.7中ConcurrentHashMap由Segment(分段锁)数组结构和HashEntry数组组成,且主要通过Segment(分段锁)段技术实现线程安全。Segment是一种可重入锁,是一种数组和链表的结构,一个Segmen
2020-12-08 14:23:33
156
1
原创 【Java】HashMap
HashMap常见面试问题1、为什么 HashMap 中 String、Integer 这样的包装类适合作为 key 键?String以及Integer这种包装类是final,保证了Hash值得不可更改性,计算精确,不会出现hash碰撞,内部已经重写equals()以及hashCode()方法。2、HashMap 中的 key若 Object类型, 则需实现哪些方法?equals():涉及到比较存储位置上是否存在需存储数据的key值;hashCode():计算数据需存储的位置,涉及的不合理就存在
2020-12-07 10:51:26
205
原创 【Java】Collection
1、ArrayList的扩容机制是什么?ArrayList在创建的时候,如果不指定初始容量,默认容量minCapacity为0,在add方法中,首先调用ensureInternalCapacity(如果minCapacity小于10,设置为10),然后调用ensureExplicitCapacity(如果现需容量minCapacity大于elementData容量,则扩容),grow的逻辑很简单。首先找出当前容量,把新容量设置为旧容量的1.5倍(通过位运算左移实现),如果扩容后容量newCapacity比
2020-12-02 22:34:35
64
原创 【Java基础】Volatile & synchronized
Volatile:在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,就需要把变量声明为volatile,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下,各任务间共享的变量都应该加volatile修饰符。Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重
2020-11-27 17:47:31
252
原创 【Java基础】单例
双检测+volatilepublic static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); }
2020-11-27 16:54:05
78
1
原创 【App】优雅的集成第三方工具
在debug模式下引入一些性能检测工具我们经常在debug模式下使用一些性能检测工具,例如blockCannary,leakCannary、Stetho等,但是我们release的时候又不需要这些检测工具,通常情况下我们的做法是在build.gradle中写上debugImplementation “xxx.xxx.xxx.xxx”这样代码里写入BuildConfig.DEBUG来实现是否调用相关方法,但是发release版本的时候没有引入这些类又会报错,所以只能手动去注释掉代码。这是何等的麻烦。因此我
2020-11-24 19:29:49
135
原创 【App】内存泄漏
这里写目录标题GCRootsGCRoots:JVM GC模型可达性分析LeakCanary 使用LeakCanary初始化检测内存泄漏⽣成heap dump ⽂件分析 heap dump ⽂件GCRootsGCRoots:1.虚拟机栈(栈帧中的本地变量表)中引用的对象;2.方法区中的类静态属性引用的对象;3.方法区中常量引用的对象;4.本地方法栈中JNI(即一般说的Native方法)中引用的对象JVM GC模型标记/清除算法、复制算法、标记/整理算法jvm采用分代收集算法对不同区域采用不同
2020-11-24 19:21:21
103
原创 【App】RecycleView优化
RecycleView优化1、Recycle缓存1.1三级缓存1.2调用notifyDataSetChanged过程2、Recycle优化:2.1 View优化2.2 setHasFixedSize(true)2.3 getExtraLayoutSpace2.4 局部刷新2.5 惯性滑动延迟加载2.6 setOnClickListener2.7 RecyclerView缓存优化2.7 数据预处理2.8 SnapHelper2.8 数据预取Prefetch2.8 DiffUtil3、遇到的问题3.1 Recy
2020-11-21 16:56:08
497
原创 【Apk】瘦身
App瘦身总结:1、代码瘦身(lint):移除无用代码、功能;移除无用的库、避免功能雷同的库;启用Proguard;缩减方法数(避免内部类调用外部变量和方法);2、资源瘦身(lint)移除无用的资源文件;Drawable目录只保留一份资源;对图片进行压缩;PNG转换JPG;使用矢量图;使用WebP;资源混淆();资源在线化;3、So瘦身在允许的情况下,针对用户机型分布保留特定架构的So;so在线化;4、7Zip压缩使用7Zip对Apk进行极限压缩。(需要重新签名)Ap
2020-11-13 11:00:51
123
原创 【App】启动优化
App启动优化:怎么测量App启动时间?adb shell am start -W [packageName]/[packageName.MainActivity]返回三个时间:ThisTime、TotalTime、WaitTime1、ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。2、TotalTime:应用的启动时间,包括创建进程+Application初始化+Activi
2020-11-11 18:17:06
275
原创 【App】启动
app启动流程apk启动涉及的“三个进程”,“六个大类”:三个进程:Launcher进程:整个App启动流程的起点,负责接收用户点击屏幕事件,它其实就是一个Activity,里面实现了点击事件,长按事件,触摸等事件,可以这么理解,把Launcher想象成一个总的Activity,屏幕上各种App的Icon就是这个Activity的button,当点击Icon时,会从Launcher跳转到其他页面。SystemServer进程:这个进程在整个的Android进程中是非常重要的一个,地位和Zygote等
2020-11-10 15:29:59
222
原创 【Apk】安装-Apk解析
APK解析Android是如何启动App的?点击屏幕上的图标,然后一个Activity就启动了,这个过程中,桌面Launcher先向AMS进程发送一个intent,AMS把这个intent发给PMS,PMS解析这个intent得到Activity的信息返回给AMS,AMS启动一个空进程,通知进程创建这个Activity,那么PMS为什么会有这个Activity的信息呢?这就是PMS解析APK要做的事情了,而解析APK的时机又要分成两种场景:系统启动时解析APKAndroid系统在启动的时候,会启
2020-11-09 14:44:02
1983
原创 【Apk】安装
Apk安装有四种方式:1、开机安装——厂商预装,没有安装界面,系统级别安装;2、网络下载安装——通过市场Market安装,没有安装界面;3、ADB安装——有安装界面;4、第三方应用安装——有安装界面。Apk安装涉及到的目录:system/app:系统预装App;data/app:用户App;data/data:用户App数据文件;data/dalvik-cache:存放Appdex文件。安装过程:把Apk文件放在data/app下,解压扫描Apk文件,把dex文件保存dalvik-ca
2020-11-09 10:03:31
171
原创 【JVM】内存回收
1、哪些资源需要回收程序计数器,虚拟机栈,本地方法栈,由线程而生,随线程而灭,栈中的栈帧随着方法的进入顺序执行,入栈出栈,栈帧内存大小在虚拟机编译期间确定的,当方法或者线程执行完毕后,就回收了,这三大模块无需关心。Java堆以及方法区,这部分的内存的分配和回收都是动态的。2、什么时候回收判断对象是否存活算法“GC Roots”的对象为起始点,搜索所经过的路径称为引用链,当一个对象到GC Roots没有任何引用跟它连接则证明对象是不可用的。要真正宣告对象死亡需经过两个过程。1.可达性分析后没有发
2020-11-03 19:01:55
111
原创 【JVM】内存模型
这里是引用JVM内存共分为虚拟机栈,堆,方法区,程序计数器,本地方法栈五个部分。程序计数器:每条线程都有自己独立的程序计数器,线程私有内存,正在执行的java方法,计数器记录的是虚拟机字节码指令的地址,如果是Native方法,计数器则为空;Java虚拟机栈:也是线程私有内存;每个方法执行的时候都会创建一个栈帧,存储局部变量,操作数,动态链接,方法返回地址;方法从开始执行到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈;通常说的栈一般是指在虚拟机栈中的局部变量部分,局部变量所需要的内存在编译期间都.
2020-11-03 16:03:58
79
原创 [Apk]打包中的zipalign
Zipalign1、Googplay平台已经不支持没有使用zipalign的apk文件上线;2、Zipalign是对spk文件中所有未压缩文件(例如图片或其他原始文件)在4个字节边界上对齐;3、他是通过修改zip文件的header section中的extra参数属性来实现对齐;4、优化后的apk运行起来后,...
2020-11-02 11:16:46
338
原创 [Apk]打包流程
Apk结构各文件作用lib:放so动态库,apk打包过程中不需要对so进行处理;META-INF:签名文件,里面有三个签名文件,有MANIFEST.MF就是对每一个文件的SHA-256-Digest,CERT.SF就是对每个文件的头三行进行的SHA-256-Digest,CERT.RSA就是保存签名和公钥证书;class.dex:就是android上可执行文件;AndroidMenifest.xml:记录应用的名字版本权限组建信息;res:资源文件;resource.arsc:编译后的二进制
2020-10-30 15:21:29
159
2
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人