Android Singleton 单例模式应用02(Multi-Thread、Synchronize)

延续 Android Singleton 单例模式应用01

在01收尾时我们举了一个需要消耗时间、资源才能初始化Singleton的例子
但通常我们在执行不能立即完成的程式一定会放在Thread中执行,主要是避免画面因为在等待未执行完的程式而卡住

延续01 Singleton的範例 这边直接加上Thread来避免画面卡住的问题
结果却发现一件很恐怖的事情,不是说好了用Singleton只会产生一个物件,怎么还是产生了两组
http://img2.58codes.com/2024/20126774MhRDcfXCax.png

再回头仔细看一下产生Singleton的判断大概就会发现
sInstance == null 这个判断大概佔不到1毫秒
new ApiRequest(context) 这个动作可能需要超过1秒的执行时间
http://img2.58codes.com/2024/20126774STNUOA46HW.png

用一个不是很专业的时间线来说明一下
onCreate中开始跑Thread A后,Activity就结束了onCreate阶段来到onResume
进入后也立即开始Thread B,但是在跑Thread B时Singleton仍未被初始化完成所以也跑了一遍初始化
就导致了虽然用了Singleton机制但仍产生了两组物件的状况
http://img2.58codes.com/2024/20126774Cl50cjBeuR.jpg

解决问题的方法 synchronized

synchronized分两种方式使用,其一是synchronized method,把某一个方法标示为synchronized,另一种则是synchronized block,是将某个程式区段标示为synchronized,这边我把两种结果都做出来

synchronized method
http://img2.58codes.com/2024/20126774yRoIwLIiBJ.png

synchronized block
http://img2.58codes.com/2024/20126774jlR0jJrnH8.png

乍看之下好像两种方式都会获得一样的结果
马上举个反例出来,synchronized block没用好的话Singleton马上就烂掉
http://img2.58codes.com/2024/201267746KjBvDF1ti.png

当然也并不是说都使用synchronized method就完全没毛病
说明一下这边範例,在getInstance前半段Sleep 3秒,这3秒可替代为任何所有程式,不影响Singleton的产生结果,但会因为synchronized method导致这段计算的程式不能同时被两个Thread使用,而导致在onCreate等待3秒,onResume再等待3秒,总共是6秒的等待时间(这边Log是onCreate及onResume的时间差,所以只有3秒)
http://img2.58codes.com/2024/20126774bXXBeTHs6U.png

马上来优化一下,把synchronized method改成synchronized block,Sleep 3秒的部分,分别在两个Thread同时执行了,所以在onCreate及onResume间几乎没有时间差了
http://img2.58codes.com/2024/20126774AyWqyRw9e0.png

结论是,我认为synchronized method及synchronized block并没有好坏之分,开发者应该要因应当下的情况选择使用的方式


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章