线程池
任务队列
SynchronousQueue:
- 这个队列接收到任务的时候,会直接提交给线程处理,而不保留它,如果所有线程都在工作怎么办?那就新建一个线程来处理这个任务!所以为了保证不出现线程数达到了maximumPoolSize而不能新建线程>的错误,使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大。
LinkedBlockingQueue
- 这个队列接收到任务的时候,如果当前已经创建的核心线程数小于线程池的核心线程数上限,则新建线程(核心线程)处理任务;如果当前已经创建的核心线程数等于核心线程数上限,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中,这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize
ArrayBlockingQueue
- 可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误,或是执行实现定义好的饱和策略。
DelayQueue
- 队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务。
拒绝策略
- 用户可以通过设置RejectedExecutionHandler实现自定义的拒绝策略,如果没有设置,将会设置一个默认的拒绝策略ThreadPoolExecutor$AbortPolicy,默认策略在执行拒绝操作的时候会抛出异常
execute和submit的区别
execute: 无返回值。入参只能为Runnable。会抛出异常
submit: 可以提供Future < T > 类型的返回值。入参可以为Callable,也可以为Runnable。不会抛出异常
四种线程池的使用场景
线程池名称 | corePoolSize | maximumPoolSize | keepAliveTime | BlockingQueue | 使用场景 |
---|---|---|---|---|---|
CachedThreadPool | 0 | Integer.MAX_VALUE | 60s | SynchronousQueue | |
FixedThreadPool | 指定的线程数量 | 指定的线程数量 | 0 | LinkedBlockingQueue | |
ScheduledThreadPool | 指定的核心线程数量 | Integer.MAX_VALUE | 10ms | DelayedWorkQueue | |
SingleThreadExecutor | 1 | 1 | 0 | LinkedBlockingQueue |
线程池的关闭
shutdown:
shutdownNow:
RecyclerView
RecyclerView 面试题 | 滚动时表项是如何被填充或回收的?
性能优化
问题
-
请说一下RecyclerView?adapter的作用是什么,几个方法是做什么用的?如何理解adapter订阅者模式?
答:adapter负责ViewHolder的创建和数据绑定
-
ViewHolder的作用是什么?如何理解ViewHolder的复用?什么时候停止调用onCreateViewHolder?
答:ViewHolder用来持有一个itemView,提供数据绑定的view对象
-
RecyclerView四级缓存
[图片上传失败...(image-8627d3-1628604203056)]
第一级缓存:从mAttachedScrap和mCacheViews中获取View
第二级缓存:从mViewCacheExtension中获取ViewHolder
第三级缓存:从RecycledViewPool中获取ViewHolder
第四级缓存:创建ViewHolder(onCreateViewHolder方法)
-
ViewHolder封装如何对findViewById优化?ViewHolder中为何使用SparseArray替代HashMap存储viewId?
答:可以通过SparseArray保存view。SparseArray比HashMap更省内存。
-
LayoutManager作用是什么?LayoutManager样式有哪些?setLayoutManager源码里做了什么?
答:LayoutManager用以处理子View的布局摆放。setLayoutManager停止了动画,并对view做了回收操作,然后重新渲染了新的layoutManager。
-
SnapHelper主要是做什么用的?SnapHelper是怎么实现支持RecyclerView的对齐方式?
答:SnapHelper用于辅助RecyclerView在滚动结束时将Item对齐到某个位置。通过attachToRecyclerView实现和RecyclerView的关联。
-
SpanSizeLookup的作用是干什么的?SpanSizeLookup如何使用?SpanSizeLookup实现原理如何理解?
答:SpanSizeLookup用来设置栅栏布局每个item所占位数大小。GridLayoutManager有一个setSpanSizeLookup方法,重写SpanSizeLookup的getSpanSize方法可以动态改变每个item所占位数大小。
-
ItemDecoration的用途是什么?自定义ItemDecoration有哪些重写方法?分析一下addItemDecoration()源码?
答:ItemDecoration可以用来给每个item绘制一些装饰物,比如分割线。
上拉加载更多的功能是如何做的?添加滚动监听事件需要注意什么问题?网格布局上拉加载如何优化?
RecyclerView绘制原理如何理解?性能优化本质是什么?RecyclerView绘制原理过程大概是怎样的?
-
RecyclerView的Recyler是如何实现ViewHolder的缓存?如何理解recyclerView三级缓存是如何实现的?
答:
屏幕滑动(状态是item状态可见,不可见,即将可见变化)时三级缓存是如何理解的?adapter中的几个方法是如何变化?
-
SnapHelper有哪些重要的方法,其作用就是是什么?LinearSnapHelper中是如何实现滚动停止的?
findSnapView 寻找对齐的view
findTargetSnapPosition 寻找目标对齐view的坐标
calculateDistanceToFinalSnap 计算到达最后对齐位置的距离
LinearSnapHelper在滚动到对齐位置后会自动停止
-
LinearSnapHelper代码中calculateDistanceToFinalSnap作用是什么?那么out[0]和out[1]分别指什么?
答:calculateDistanceToFinalSnap用来计算到达最后对齐位置的距离。out[0]横向需要滚动的距离,out[1]纵向需要滚动的距离
如何实现可以设置分割线的颜色,宽度,以及到左右两边的宽度间距的自定义分割线,说一下思路?
如何实现复杂type首页需求?如果不封装会出现什么问题和弊端?如何提高代码的简便性和高效性?
-
关于item条目点击事件在onCreateViewHolder中写和在onBindViewHolder中写有何区别?如何优化?
答:onCreateViewHolder只会被调用一次,onBindViewHolder会被多次调用
RecyclerView滑动卡顿原因有哪些?如何解决嵌套布局滑动冲突?如何解决RecyclerView实现画廊卡顿?
RecyclerView常见的优化有哪些?实际开发中都是怎么做的,优化前后对比性能上有何提升?
-
如何解决RecyclerView嵌套RecyclerView条目自动上滚的Bug?如何解决ScrollView嵌套RecyclerView滑动冲突?
给其他控件设置焦点
外部拦截法和内部拦截法
-
如何处理ViewPager嵌套水平RecyclerView横向滑动到底后不滑动ViewPager?如何解决RecyclerView使用Glide加载图片导致图片错乱问题?
解决滑动冲突
给ImageView设置一个Tag