OkHttp源码之缓存文件的并发控制

2018-12-08  本文已影响20人  低情商的大仙

在前两篇文章中我们详细的介绍了okhttp缓存文件的结构,缓存的详细读写过程以及缓存文件的清理机制,今天,我们大致介绍下缓存文件最复杂也是最容易出错的部分:并发控制

涉及的所有文件

在开始之前,我们先分析下整个okhttp缓存过程中涉及到了哪些文件:

文件名称 何时创建 何时写入 何时读取 何时销毁
journal 初始化时 初始化时写入5行头部;
缓存写入,读取,删除
初始化时 不会销毁,会在重建时被新文件替换
journal.tmp 重建journal文件时 重建journal文件时 只会替换成journal,不会直接读取 重建journal文件完成后被删除
journal.bkp 重建journal文件时,原有journal重命名成.bkp文件 重建journal文件完成时;初始化时
xxxx.0.tmp 缓存Header写入时 cache的put执行时 只会替换成xxx.0文件,不会读取 put执行完成后会重命名成xxx.0
xxxx.0 Cache put完成后原有的xxxx.0.tmp重命名成 不会直接写入 调用Cache的get方法时 压缩journal文件时;删除某个请求的缓存时;缓存完毕时被其他.0.tmp替换
XXX.1.tmp 缓存body时创建 读取body信息时顺便复制数据写入 只会替换成XXX.1文件,不会直接读取 body缓存完毕后会删除
xxx.1 body读取最后close的时候原有的xxx.1.tmp重命名成 不会直接写入 缓存调用get时获取一个body,该Body读取时 压缩journal文件时;删除某个请求的缓存时;缓存完毕时被其他.0.tmp替换

如何防止同时创建文件

靠synchronized关键字保证

如何防止写入冲突

靠synchronized关键字保证

如何防止读写冲突

所有文件的写入操作都是写到一个文件的.tmp临时文件中,这个时候读还是从原来的文件读,写入不会污染原来文件,写入完成后会将.tmp文件替换掉原有文件,这样完美解决读写冲突。

如何防止删除和读写冲突

其实对于缓存来说,文件的可靠性要求不是很高,缓存失效的情况下,我们不使用缓存,直接从网络获取就可以了。正是基于这种思想,okhttp并不存在在删除时检查是否有线程正在写入或读取的行为,而是直接删除,在读写时做好容错处理,对被破坏的数据直接丢弃,转而从网络请求获取数据。

上一篇下一篇

猜你喜欢

热点阅读