
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
1.4 在Java中如何使用多线程
在Java中实现线程的方式有很多:继承Thread类、实现Runnable接口、使用ExecutorService线程池、使用Callable/Future实现带有返回值的多线程,等等。因此,在Java中开发一个多线程应用非常简单,本节将介绍具体方法
1.4.1 实现Runnable接口创建线程
Runnable是声明一个线程的接口,使用方法如下。


注意:线程是通过thread.start()来启动的,线程启动后,会异步执行RunnableThreadExample中的run()方法。
1.4.2 继承Thread类创建线程
Thread是一个类,可以直接继承该类来创建线程,使用方法如下。

Runnable和Thread的区别在于,前者是接口,后者是类。如果当前需要实现线程的类已经集成了另外一个类,就无法再通过集成Thread类来实现线程,只能通过Runnable接口来完成。
Thread类也实现了Runnable接口,即一个线程实例。启动线程的方法仍然是通过Thread类的start()实例方法来完成的。
1.4.3 实现Callable接口并创建带返回值的线程
在有些场景中,我们可能需要让一个异步执行的任务在执行完成后返回一个结果。而前面使用的线程中,run()方法是一个void修饰的无返回值的方法,很显然无法达到我们的要求。因此在Java中提供了Callable和Future来创建有返回值的线程,实现代码如下。


从上述代码中可以看到,Callable接口提供了一个带有返回值的call()方法,接着定义了一个FutureTask,来表示一个获取未来执行结果的任务,并使用Thread线程来执行,最后通过futureTask.get()方法来获得执行结果。
这种方式并不是目前最好的选择,在后续章节中笔者会详细说明它的原理及最佳实践方案。