日常开发中,多线程编程是个难以避免的话题,开发者可以小心翼翼、谨慎地、严谨地编程来编写出高效的、安全的多线程程序,但是在长时间的维护中,难免因为其中某个人的某个疏忽而导致出现预料之外的并发问题,比如下面这个简单的类:
class TestActivity extends Activity{
public void refreshView(){
//...
}
}
非常常见的一个类,在Android中只有在主线程可以更新界面,可能一开始写的时候并没有考虑其他线程调用refreshView
方法。然而随着项目推进,终于有一天,某段其他线程的代码出于方便直接调用了这个方法,恰好编写调用的开发者没有来检查这个方法是否线程敏感。
解决这类问题很简单,发现问题的时候补上线程检查或线程切换的代码就好了,但这样没法避免下次犯同样的错误。建立良好的代码规范、谨慎编写并及时review可以减少这类问题的出现,但现实开发中有时候会比较仓促,需要一种比较强制性的、便利的、安全的做法来处理这类隐患。
以前在学习Actor多线程模型的时候,了解到将Actor和线程相关联是一个简单且安全的方案,但如果像Actor模型中那样Actor之间利用消息通信在处理这个问题时就显得有些麻烦,差不多需要重构模块间通信方式了。
那么有没有一种简单粗暴的方法可以像Actor模型那样使得“某个类的方法只在某个线程中执行”并且在“进入这个类的方法时自动切换到对应线程”呢?。本文就介绍一种利用动态代理来完成这个任务。
示例场景
Android开发中有两种非常常见的线程敏感场景:1. 只有主线程可以更新界面;2. 不能在主线程进行IO操作或复杂长时间计算。
第一种场景比如下面这段(这里的showSum
是一个线程敏感方法,必须在主线程调用):
public interface ViewActor {
void showSum(int sum);
}
class ViewActorImpl implements ViewActor {
TextView tvSum;
@Override
public void showSum(int sum) {