美文网首页
通过例子讲解多线程中外星方法的危害以及如何避免

通过例子讲解多线程中外星方法的危害以及如何避免

作者: 每天学点编程 | 来源:发表于2018-02-18 02:12 被阅读22次

请关注我的微信公众号

个人微信公众号

技术交流群 (仅作技术交流):642646237

​请关注我的头条号:

例子



addListener()removeListener()updateProgress()是同步方法,多线程可以安全地使用这些方法。

例子的问题——外星方法对多线程的隐患

updateProgress()调用了外星方法。

外星方法可以做任何事情,例如持有另外一把锁。这样一来,程序就在对加锁顺序一无所知的情况下使用了两把锁,这样就有可能发生死锁。

例子的问题——如何避免

唯一的解决思路是避免持有锁时调用外星方法。

例子的问题——如何避免——保护性复制

在遍历之前对listeners进行保护性复制(defensive copy),再针对这份副本进行遍历:

在调用外星方法时不用加锁,而且大大减少了代码持有锁的时间。长时间地持有锁将影响性能(降低了程序的并发度),也会增加死锁的可能。
保护性复制也修复了与并发无关的另一个bug——修复后如果监听器在onProgress()中调用removeListener(),将不会影响到正在进行遍历的副本。

相关文章

网友评论

      本文标题:通过例子讲解多线程中外星方法的危害以及如何避免

      本文链接:https://www.haomeiwen.com/subject/vbbvtftx.html