题目
为什么使用 start 启动线程,而不使用 run 方法启动线程
答案
`run()` 方法被称为**线程执行体**,它的方法体代表了线程需要完成的任务,而 `start()` 方法用来启动线程。 调用 `start()` 方法启动线程时,系统会把该 `run()` 方法当成线程执行体来处理。 但如果直接调用线程对象的 `run()` 方法,则 `run()` 方法立即就会被执行,而且在 `run()` 方法返回之前其他线程无法并发执行。**也就是说,如果直接调用线程对象的 `run()` 方法,系统把线程对象当成一个普通对象,而 `run()` 方法也是一个普通方法,而不是线程执行体**。 > 举个例子: > > ```java > // 创建线程 > Thread t1 = new Thread("t1") { > @Override > // run 方法内实现了要执行的任务 > public void run() { > // 线程需要执行的任务 > System.out.println("开始执行"); > FileReader.read(文件地址); // 读文件 > } > }; > > t1.run(); > System.out.println("执行完毕"); > ``` > > 如果使用 run 方法启动线程,"执行完毕" 这句话需要在文件读取完毕后才能够输出,也就是说读文件这个操作仍然是同步的。 > > 而 **`start` 方法会调用一个私有的 native 方法 `start0` 去创建新的线程**: > > ![](https://cs-wiki.oss-cn-shanghai.aliyuncs.com/img/20220615161227.png) > > 使用 start 方法启动线程,"执行完毕" 这句话在文件读取完毕之前就会被很快地输出,因为多线程让方法执行变成了异步的,读取文件这个操作是 t1 线程在做,而 main 线程并没有被阻塞。