最近看到两段相似的代码,第一段是
java
public class Main {
public static void main(String[] args) {
new Thread(() -> {
doWork();
}).start();
}
static void doWork(){
//执行耗时操作...
}
}
第二段为
java
public class Main {
public static void main(String[] args) {
doWork();
}
static void doWork() {
new Thread(() -> {
//执行耗时操作...
}).start();
}
}
两段代码的差别仅在启动线程的位置。
有时候写程序比较随意的时候,两种形式的代码都可以可能出现,下面记录下我对这种形式的一些想法。
第一种:由调用方来控制线程启动
这种对应上述在main
方法中启动线程的情形。这种形式最初看到的时候是在Android的一个Activity
的代码里,因为Activity
的诸多方法运行在主线程中,如果执行耗时操作,那么就会导致ANR程序不响应,那么就会把一些认为是耗时的操作放在其他线程中,于是就有了类似的代码:
java
public class DemoActivity extends Activity{
@Override
protected void onResume() {
super.onResume();
new Thread(() -> {
xxManager.startDoWorks();
}).start();
}
}
第二种:由实现方来控制线程启动
这种对应上述第二种在doWork
方法中启动线程的情形。这种代码最初是在一个Controller
的代码中看到,因为这个类中包含了一些网络和文件访问的操作,所以接口方法都另起线程来执行:
java
public class DemoController{
public void doXXXWork(Callback callback){
new Thread(() -> {
//执行耗时操作...
}).start();
}
}
对比和思考
虽然两种代码我都写过,但我还是倾向于后者由实现方来控制线程启动。理由如下:
- 实现方知道内部代码的具体实现,可以决定内部代码在哪种类型的线程中执行。而调用方需要查看实现方的代码才能知道。
- 实现方对实现的代码有着控制权,可以变更代码实现,根据实现方式来调整线程的使用。
- 调用方去改变外部代码的线程上下文有点越权的感觉,这不应该是调用方的职责。