这是我参加8月更文应战的第6天,活动概略查看:8月更文应战
线性表
常见的线性表有两种: 次序表和链表,我们先来diff下两者差异。
次序表
次序表是依据数组结束的,比方ArrayLi复杂度符号st,由于次序,okhttpclient所以要占用一块接连的内存空架构间,因复杂度怎样核算的为不接连就不次序了,由于要占用连okhttpclient续的内存空间,所okhttp是干什么用的以是比较egg pain架构图模板的。
首要,它不费内存,由于只需求存储元素值就行了。可是,它要接连的内存空间,就像住酒店似的,我有许多空房,可是不挨着,你非要一串挨着的,我得跟其他客人说说,让人家腾出来,给你弄几间挨着的,体现在代码中便是:
或许会复杂度最高的是再三触发GC,由于没有接连的内存空间,需求将内存从头整理一下,给你腾出来接连的内存空间。所以它的线程池这个特征能够okhttp运用概括为为: 空间占用小,可是要接连。
第二,它是支撑随机拜访的接口无权限是什么意思,由于是接连的内存空间,所以我只需按线程数着序号去找就行了,比方它住了酒店二楼,从1号房初步住到10号房,我要去找第9个客人,直接去敲9号门就行了,一步到位。可是,它的删架构师和程序员的差异去功率极低,线程是什么意思比方复杂度o(1)什么意思,现在5号房间要退房,让5号走就行,可是,它明晰了要接连的内存空间,所以5号房间假定空出来,就不接连复杂度英文了,还得让6号复杂度o去5号,7号去6号…以此类推,有人说:直接让最后一个人(10号)搬到5号不就行了,不可!
由于这样就破坏了次序(10号本来在9号后边,现在跑到了前面),肯定是不可的,所以只能让后边的顺次向前挪,同理,假定有个人要来住到5号房间,那又复杂度怎样核算的要顺次向后挪。它的这两个特征可线程池创立的四种以概括为: 长于拜访,不长于刺进删线程安全去
所以,能够总结为: 次序表是有序的,不耗内存但需求占用接连的内存空间,利于随机拜访,不利于刺进删去
次序表在开发中的用处可太多了,比方ArrayList,就接口卡像LOL中的草丛伦,可谓新手独爱,直接记事本就敲出来:
List<Strin架构g> list = new ArrayList<>();
常常用在RecyclerView或ListView的适配器中,这个不废话了。
这儿其实okhttp运用能够简略的统筹一下ArrayList的运用当地: 但凡不触及删去刺进的都能够用这个,比方拉服务器数据展现,检索数据库数据展现等。
可是有一点要注意,List存储Integ接口测验er的时分,调用remove()办法,必定要注意参数是Object仍是index:
// 这两个办法很相似,元素是Inokhttp面试题teger时分,remove(10)默许是remove(inokhttp运用dex)的
E remove(int index);
boolean remove(Object o);
这是一个坑点,复杂度怎样核算的由于大部分人都不看回来值的,想调用remove(Object)的,能够用包装类型转化一下即可。
链表
链表可谓是新手杀手,一个链表倒置算法都架构师证书能干死一大批人。其实只需明白了原理就能把它按在地上抵触到死架构师薪酬一月多少。
链表的中心是链,比方最简略的单链表,每个节点除了存储元素值,还有个引用,执向它后边的邻接点,这个引用便是链表的中心,链表是比较费内存的,由于多存了个引用嘛。
// 链表的节点
class Node {
// 存储元素值
Objec架构图模板t value;
/接口测验/ 存储它后边的邻接点
Node next;
}
但接口测验面试题是,它对内存的要求不高,不需求连复杂度英文续的内存空间,比方,仍是住酒店,它们不需求挨着的房间,比方:A说,我住这间,然后它持有B的微信,B说,我住这间,它持有C的微信,以此类推….这样,房间也不必挨着了,自己住自己的就行,并且,假定B走了,C也不okhttp3运用详解用跑到B的房间住,只需线程安全求让B把C的联络办法给A,就行了,线程池创立的四种这样A和C就连接起来了,很便当。可是它有个缺点: 不支撑随机拜访。比方,我要找它们中的D,我不知道D在哪架构师,我得先去找A,然后通过它的微信复杂度o找到B,然后再通过B的微信找到C,再通过C的微信找到D..,
所以,它的这些接口是什么特征能够概括为: 链表是比较耗内存,可是不需求接连的内存空间,利于刺进删去,不利于随机拜访
我们假定有链表:A接口和抽象类的差异 -> B -> C -> D,我们想将B删去,有人说,直接让A->C就行,不可!由于A只能找到B,不能直接找到C,所以我们需求: 让A手里的微信变为B手里的微信即可。那么便是A.next = B.next即可。
同理,假定我们要在A和B之间刺进E呢,也便是要变成: A -> E -> B -> C -> D。我们接口无权限是什么意思知道,这样需求 让E有B的微信,A有E的微信 即可,那么,我们能够先让A手里微信变为E,再让E手里的微信变为B。线程等等,有问题,假定先让A手里的微信变为E,那么A就没有B的微信了,E去哪找B的微信呢,接口类型E直接去找B要吗?不可!由于找B首要要去找复杂度最优A要B的微信,可是现在A也没有B的微信了。
所以我们应该: 先让A把B的微信给E,然复杂度英文后再让A手里的微信变为E,由于E就在这站着呢,A能够直接okhttp封装找复杂度英文到E去要它的微信。也便是:
E.next = A线程的几种状况.next; // A先把B的微信给E
A.next = E; // A在把手里的微信变为E
所以我们处理链表有个窍门: 1 先把想要的作用列出来,2 然后将 前面的改动 会引起后边改动 的操作 放到后边,比方刚刚的比方:
- 先把作用列出来:A.next = E; E.next = A架构师和程序员的差异.next;架构图怎样做word
- 然后排序:
// 次序1
A.next = E; // A.next改动了
E.nokhttp3运用详解ext = A.next; // 这儿要用A.next架构图模板,可是前面现已修改了A.next了,okhttpclient引起了这儿的改动,不可。那就需求将前面的改动放到后边
那么,我们就需求调整次序了:
E.next = A.next; // 修改了E.next
A.next = E; // 修改复杂度排序了A.next,这儿没有用到E.next,前面架构师薪酬一月多少改了也没问架构题
所以,链表类的算法,窍门就接口测验面试题是: 1 列作用 2架构师证书 调整次序,将引起后边改动 的操作 放到后边,当然,某些状况复杂度符号下或许需求引入暂时变量,这儿不再深化谈论。
那么,链表在娜些开发场景中适用呢,便是: 刺进和删去再三的当地。比方: 一个直播间的房间线程池成员列表,成员再三进入退出,退出的时分我就要从列表删去这个人。抽象的说: 但凡触及再三刺进删去元素的当地,都应该用链复杂度符号表。
综上,我们知道次序表和链表都是有序的,它线程池面试题们都是按增加元线程数素的次序有序。其间,次序表拜访功率高,刺进删去功率低,不消耗内存可是需求接连的内存空间;链表拜访功率低,刺进删去功率高,比较耗内存可是不需求接连的内存空间。
映射表
映射表的家族比较大,能够细分为许多,可是常用的就几种:
- HashMap: 最基础的映射表,依据链表数组和红黑树结束的,无序的,抱负状况下存取功率为O(1),可是比较费内存。线程安全
- Treokhttp长处eMap: 依据红黑树结束的,依照key有序的,由于添okhttp是干什么用的加/删去元素触及到树的旋转操作,所以时刻复杂度是log(n)的。
- LinkedHashM线程池创立的四种ap: 跟HashMap线程池的结束原理是相同的,不过内部多了维护元素次序的链表,是依照元素增加的次序有序的,并且能够指定是否主动调整最新的元素到头部,能够用来结束LRUCache。
- ConcurrentHashMap:接口测验面试题 依据分段锁结束的,支撑必定粒度复杂度最优的并发存取,由于内部的结束原理是CAS,所以功率比一般的Synchronized系列高。接口是什么
Android中的API:
- ArrayMap: 依据彻底二叉树结束的,跟HashMap的功用根本相同,存取功率比HashMap低,为log(n),可是很省内存,内部只需两个数组,一个架构图怎样做word存hash,一个存key和value。
- SparseArray: 跟HashMap相似,可是Key只能线程安全是Integer,存取功率为接口测验面试题log(n),复杂度排序很省内存,内部只需两个数组,一个为key,一个为value。
我们能够架构师薪酬一月多少看到,Android中供应的API,大都是以接口是什么省内存为目的的,这在内存贵重的移动端,确okhttp原理实是很正确的。
所以,在Android开发中,假定你的key是Integer线程和进程的差异是什么,建议优先运用SparseArray;否则建议运用ArrayMap。当然,假定你对功能要求极okhttp运用过程高,对内存要求不高,则能够运用HashM架构图用什么软件做ap,假定你需求依照ke复杂度怎样核算的y有序,则能够运用TreeMap,假定是依照存放次序有序,则能够运用LinkedHashMap,假定是并发场复杂度英文景,则能够运用ConcurrentH接口无权限ashMap。
比方说,我要维护一个老友列表,并且能够依据接口crc错误计数id找到老友,那么就需求一个id-老复杂度符号友这样的映射,假定id是Integer类型的,我们能够运用SparseArray,假定id是String类型的,我们能够运用Arra架构图yMap。
再比方,一个音乐App,用户有个”喜欢列表”,复杂度o(1)什么意思能够依照用户保藏的次序增加进去,一同能够依据歌曲名字查找,那么这儿有两个要害点: 1 依照增加有序 2 能查找。假定只是依照增加有序,用ArrayList或许LinkedList就行了,可是这样的话,依据歌名查找就需求遍历,功率太低了,那么既然是依据歌名查找,肯定线程池面试题有个: 歌名-歌曲映射。所以我们要选用映射表,又由于是依照增加有序,所以我们运用Link接口是什么edHashMap。
LinkedHashMap在创立的时分,能够指定acces线程池的七个参数sOrder线程撕裂者参数,假定为true,则会主动排序,将最新拜访的元素放在okhttp运用过程前面,这样能够保证前面的元素是最近拜访的,能够运用这个来结束LRUCache。
举个比方,假定我们要做一个app,需求在本地缓存老友列表,那么我们能够建立一张friends表,保存自己的老友,可是,假定有一天,我在这台设备上登录了另一个账号,那么获取的老友列表便是上一个账号的老友列表,所以,我们要依据不同的用户id建立多张表,让老友表跟用户id对应起来,可是又有问题了,假定我在这台设备挨个登录100个账户呢,难不成手机上存100个friends表?不可,这是okhttp长处手机,不是服务器,太费存储空间了,所以我们能够束缚每台设备最多只存3个friends表,那么登架构师需求把握哪些常识录了第4个账号怎样办呢,我们删去第复杂度一个登录的吗?不对,我们应该删去最近最少登录的,也便是说: A登录,B登录,C登录,A登录,A虽okhttp运用然是第一个登录的,可是最近他又登录过了,架构图模板那么B就成了最近最少登录的了,也便是最远登录的了,所以我们应该删去B账户的friends表。可是这样还有问题,假定我的登录次序是: ABBBBBBBBBBCA,这样,你还删去B吗?不应该,由于B这么一okhttp长处再登录,我们能够以为他是个常用用户,C和A只是偶然上来看看,所以我们应该删去C,总的来说,我们不应该只是记载登录时刻,还要记载登录次数,两个结合起来最少的那个,才应该被删去,这便是最近最少运用(Least Recent Use),也便是LRU。我们的LRUCache便是这么个原okhttp运用过程理。
所以,LinkedHa线程的几种状况shMap适合要依照元素存放次序 或许 要结束一个LRU缓存的场景。
TreeMap是依照key有序的,它是依据红黑树结束的,也便是说,每个元素的左孩子都比它小,右孩子都比它打,每次puOKHttpt或许remove元素的时分,都会调整到这种次序,所以,它是依据二分的思维设计的。当我们需求元素有序的时分,就能够运用TreeMap。
至于ConcurrentHashMap,大部分人线程都很少用的,记住一点就行: 并发的时分,线程优先用它,由于关于客户端来说,高并发的场景很少见。
综上复杂度比较,在移动端开发中,当我们的key是Integer时,用SparseArray,否则就用Array线程Map;要依照元素存放有序的 或许 结束LRU缓存,就用LinkedHashMap;当期望能够自界说排序的线程的几种状况时分,用TreeMap;遇到并发的时分,接口无权限运用ConcurrentHashMap即可。
栈与部队
栈和部队,接口测验其本质也是线性表,不过元素的出入次序比较特别。
栈:先进后出,部队:先进先出。okhttp源码剖析换句线程撕裂者话,栈是对前史进行架构图怎样做word回溯,部队是对前史进行复原,回溯是从后往架构师需求把握哪些常识前okhttp原理的,复原是早线程年往后的。
栈在开发中的运用很少,可是却无处不在,比方我们常见的办法调用:
void funA() {
funB();复杂度怎样核算的
}
void funB() {架构图怎样做word
funC();
}
void funC() {
}
其实在Jokhttp面试题VM里边,有个办法栈,每个办法调用的是否都会创立一个栈帧复杂度o(1)什么意思并入栈,也便是说: fokhttp运用unA()入栈,funB()入栈,funC()入栈,然后实施funC(),然后将funC()出栈,并把回来值给funB(),然后实施funB(),然后funB()出栈,并把作用给funA(),然后funA()出栈。
入栈: funA() -> funB() -> funC();
出栈: funC()架构师需求把握哪些常识 -> funB() -> funA();
所以,JVM的办法调用是依据栈结束复杂度排序的。这也体现了回溯的思维: 从这条路曩昔,沿着这条路回去!
部队在开发中很常见,无处不在,比方我们要结束个下载器来排队下载,那么就能够创立一个Queue,每次有使命过来,先增加到Queue里边,然后检测当前是否有使命下载,假定有,就算了,没有就出队并下载,下载完后再检测部队是否还有使命,有就出队并下载,以此类推。
部队在源码中的运用也许多,比方最常见的Handler里边的MessageQueue,再比方OkHttp里边的央求部队便是个双端部队,也是部队的一种。其实LinkedList也是一个双端部队,只不过部队是一种抽象的概念,而架构师和程序员的差异LinkedList是部队的一个具体结束。
然后我们来看下优先级部队PriorityQueue。Prio架构图用什么软件做rit接口测验面试题yQueue是依据堆结束的,其本质是一个彻底二叉树,能够分为大顶堆或小顶堆,大顶堆便是根节点最大,小顶堆便是根节点最小,线程和进程的差异是什么并且,每次增加或许删去元素的时分,它会主动调整,使得剩余元素仍接口crc错误计数然是大顶堆/小架构是什么意思顶堆,并且,遍历大顶堆,每次得到的元素都是最大的那个,小顶堆则是最小的那个。
那么,优先级部队有什么用处呢,我们先来okhttp3运用详解写个简略的观察者办法: 用户能够从书店订阅书本改动的音讯:
// 界说书本实体
class Book {
String name;
String title;
}
// 观复杂度o(1)什么意思察者接口
interface Observer {
void onBookChanged(Book book);
}
// 界说书店
class BookStore {
// 观察者集接口类型结
private List<Observer> obs接口测验面试题ervers = new ArrayList<>();
// 增加观察者
public v线程撕裂者oid addObserve复杂度最高的是r(Observer observer) {
if (!obse架构图用什么软件做rvers.contains(observer)) {
observers.add(observer);
}
}
// 移除观察者
public void removeObserver(Observer observer) {
observers.remove线程是什么意思(obsOKHttperver);
}
// 奉告观察者改动
private void notify(Book book) {
for (Observer observer : observers) {
observer.onBookChanged(book);
}
}
// 修改书本
void chang线程和进程的差异是什么eBook(Book book) {
book.name = "andr线程撕裂者oid";
notify(book);
}
}
代码很简略,都能看懂,我们复杂度最优结束了一个观察者办法,当有书本修改时,无差别的奉告观察者,可是:现在遽然有一天,老板说: 假定书本有改动,先奉告我,我怎接口类型样才华保证先奉告老板呢?我们有两种计划:
- 1 在BookStore里边增加一个独自的观察者,表okhttp运用过程示老板,那么代码就相似下面这样:接口测验
// 界说书店
class BookStore {
priv接口测验ate List<Obse接口rver> observers = new ArrayList<>线程;();
// 增加了一个老板观察者
private Observer bossObserver;
//架构师证书 这是注册,也是反注册,传nu接口ll便是反注册
public void setBossObserver(Observer bossO架构图bserver) {
this.bossObserver = bossObserver;
}
public void a接口测验ddObserver线程池的七个参数(Observer observer) {
if (!observers.contains(observer)) {
observe架构师rs.add线程是什么意思(observe线程池面试题r);
}
}
public void removeObse复杂度rver(Observer observer) {
observers.remove(observer)架构师证书;
}
private void n接口是什么otify(Book book) {
// 先奉告老板
if (bo线程池的七个参数ssObser复杂度怎样核算的ver!=null) bossObserve线程安全r.onBookChanged(book);
// 再线程安全奉告其okhttp面试题他人
for (Observer obse线程是什么意思rver : observers) {
obse架构图用什么软件做rver.onBookChanged(book);
}
}
void changeBook(Book book) {
book.name = "android";
notify(b接口卡ook);
}
}
这样能够吗?能够,但okhttp原理是,这是什么狗屁办法?有注册和反注册,还有setter函数,不三不四的,并且!最okhttp源码剖析重要的是:假定你有二老复杂度o板三老板呢,难不okhttp封装成继续增加成员变量吗,肯定是不可的!这样维护起来太吃力了,并且,作为一个书店,还得知道谁是大老板,谁是小老板,其实作为书店,是不应该知道这么细的,这不符合最少常识原则。甚至架构师有一天: 大老板说,你先发给二老板,然后再发给我,….无解!
那么,能够处理吗,能够的,我们运用第二种办法,便是: 让观察线程安全者有序,我们书店只管分发就行,只需观察者是有序的,那么终究就会按正确的次序分发到老板和用户手中,线程我们这样改:
// 继承Compokhttp3运用详解arable
interface Observer extends Comparable<Observokhttp封装er> {
// 观察者的优先级
int priority();
// 奉告的回调
void onBookChanged(Book book);
// 默许结束比较函数,优先级高的先被分发到
@Over架构师和程序员的差异ride
default int compareTo(Observer o) {
return o.priority() - p架构师riority();
}
}
我们的Bokhttp运用ookStore需求稍微修改一下:
// 定OKHttp义书店
class Bo架构图okStor接口e {
// 观察者集结
private List<Observer> observers = new Aokhttp面试题rrayList<>();
// 增加观察者
public void addObserver(Observer observer) {
if (!observ线程池面试题ers.contains(observer)) {
observe复杂度最优rs.add复杂度英文(observer);
// 增加了新观察者需求排架构师证书序
Collec接口测验tions.sort(observers);
}
}
// 移除观察者
public void removeObserver(Observer observer) {
observers.remove(observer);
// 删去了观察者需求排序
Collections.sort(observers);
}线程安全
// 奉告观察者改动
priva线程安全te void notify(Book book) {
for (Observer observer : observers) {
observer.onBookChanged(book);
}
}
// 修改书本
void changeBook(Book book) {
book.name = "android";
notify(book);
}
}
改动很少,我们每次增加或删去观察者时,从头排序一下即可。那么,有没有更简略的办法呢,有!用优先级部队,咱接口无权限们前面说过,线程池的七个参数优先级部队,每次增加/删去元素会主动排序,并且遍历架构师证书的时分,保证每次得到的都是剩余的最大/最小的元素,我们修改BookStore如下:
// 界说书复杂度店
clas架构s BookStore {
// 观察者集结,运用PriorityQueue
private PriorityQueue<Observer> observers = new Pr接口iorityQueue<>();
// 增加观察者
public void addObserver(接口crc错误计数Observer observer) {
if (!observers.contains(observer)) {
// 这儿调用的是offer
observers.offer(observer);
}
}
// 移除观察者
public void removeObserver(Obse架构师需求把握哪些常识rv线程池创立的四种er observer) {
observers.remove(observer);
}
// 奉告观察者改动
private void notify(Book book) {
for (Observer observer : observers) {
observer.onBookChanged(boookhttpclientk复杂度o(1)什么意思);
}
}
// 修改书本
void changeBook(Book book) {
book.name = "android"okhttp运用;
notify(book);
}
}
代码很简略,我们复杂度o(1)什么意思只是替换观察者集结为PriorityQueue,一同增加观察者运用offer()。上述代码扩展架构师和程序员的差异性很强,想怎样调整观察者次序都能够,BookStore彻底不必架构图变,可是有个风险,便是Observer能够随便回来自己Priority,不是老板也可复杂度o(1)什么意思以回来老板的Priokhttpclientority,所以我们要将权限缩okhttp运用小,能够运用枚举,也能够运用check机制,这儿不再废话。
依据上述代码,我们能够自己建立一个NB的结构,我们能够界说一个作业分发器,一个数据处理器,一个UIokhttp运用过程处理器,当服务器数据接口测验面试题过来时,我们会先在作业分发器接收到,然后分发给数据处理器,数据处理器会解析并保存数据,然后作业分发器接着分发给UI处理器,这时分UI处理器直接去数据处理器里边获取数据即可,代码大致如下:
// 运用枚举界说优先级
enum Priority {
DATA(10),
UI(0);
int priority;
Priority(int prior线程是什么意思ity) {
this.priority = priority;
}
}
interface Obser复杂度over extends Comparaokhttpclientble<Observer> {
Priority priority();
void onBookChanged(Book book);
@Override架构师需求把握哪些常识
default int comp接口无权限是什么意思areTo(Observer o) {
return o.priority().priority - pri复杂度ority().priority;
}
}
class DataHandler implements Observer {
@Override
public Priority priorokhttp原理ity() {
// 回来DATA的优先级
return Priority.DATA;
}
@Over线程撕裂者ride
public void onBookChanged(Book book) {
/okhttp源码剖析/ 存储数据
}
}
class UIH接口主动化andler implements Observer {
@Override
public Priority priority() {
// 回来UI的优先级
return Priority.UI;
}
@Override
public void onBookChanged(Book book) {
// 获取并展现数据
}
}
上述代码描绘了大概的逻辑,只需了解这个思路,我们的应用程序架构肯定会接口测验面试题灵活的多。
原子类型
原子类型指的是AtomicInteger、AtomicBoolean等Atomic一族的类型,它们是依据CAS结束的,是线程安全的。
我们必定遇到过在lambda中运用一个局部变量,可是提示有必要为final的问题,要害是要在lambda修改,怎样能声明为final呢,估量这时分有人就去给它提取为成员变量了,这是不对的,这时分就能够用Atomic接口测验面试题一族了。
比方,如下代码: 首要用本地url,假定服务器又回来,就用服务器的,
void test() {
// 先取本地url
String url = "ht线程池面试题tp://www.baidu.com";
// 获取服务器url
HttpAPi.okhttp面试题getRealUrl("url/data", (b线程池面试题ean) -> {
runOnU接口无权限iThread(()接口crc错误计数 -> {
if (bean != null) {
if (!TextUtils.isEmpty(bean.url)) {
// 又回来,就用服务器url,可是这儿报错了,提示在lambda里只能用fina架构是什么意思l,mmp的!
url = bean.url;
}
}
// 打印,又报错
println(url);
});
});
}
上述提示说,在lambda里边只能拜访final修饰的变量,可是我想修改它,又不能用final修饰,he mather!上Atomic!,代码如下:
void test() {
// 先取本地url。这儿创立一个AtomicReference
AtomicReference<String>架构是什么意思; url = new AtomicReference<>("http://www.baidu.com");
// 获取服务器url
HttpAPi.getRealUrl("ur接口类型l/da复杂度符号ta", (bean) -> {
runO接口nUiThread(() -> {
if (bean != null) {
if (!TextUtils.isEmpty(bean.url)) {
// 这儿直接set就行
url.set(bean.url);接口和抽象类的差异
}
}
// 打印,直接口crc错误计数接运用get()获取架构
println(url.gokhttp面试题et());
});
});
}
能够看到,At架构图怎样做wordomic系列就像一个仓库,运用put/ge接口t存取,很便当。并且它是依据CAS的,是豁达的,不存在功率方面的问题。
总结
- 非映射联络,okhttp运用过程随机架构图拜访多,刺进删去少的,运用ArrayList;反之则运用L线程数inkedList。
- 映射联络,key是Integer的,运用Spar复杂度符号seArray,否则运用ArrayMap;假定对功能要求比较高,能够运用H线程池的七个参数ashMap,假定要求依照存放有序,或许结束LRUCache,则运用LinkedHashMap。假定需求自己排序,则能够运用TreeMap,假定有并发场景,则运用Concurrenokhttp运用tHashMap。
- 要求先进先出,考虑运用Queue,先进后出则运用Stack,要求元素自线程数动排序,则可复杂度排序以运用PriorityQueue,遇到lambda运用/修改局部变量,则能够运用Atomic系列。