![Java并发编程深度解析与实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/971/43737971/b_43737971.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
1.4 在Java中如何使用多线程
在Java中实现线程的方式有很多:继承Thread类、实现Runnable接口、使用ExecutorService线程池、使用Callable/Future实现带有返回值的多线程,等等。因此,在Java中开发一个多线程应用非常简单,本节将介绍具体方法
1.4.1 实现Runnable接口创建线程
Runnable是声明一个线程的接口,使用方法如下。
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-024-1.jpg?sign=1738806011-SEdDJTA6ZHW1QSiBGalXcUFVLoPCQ0Bm-0-e80be05fde55a82b2ccc46b6c369e59e)
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-025-1.jpg?sign=1738806011-5GibH0ZTyQdPPZJRD3AjcLP5KnHef4Eh-0-ea61cb68f62b42e1459234a87d4bf251)
注意:线程是通过thread.start()来启动的,线程启动后,会异步执行RunnableThreadExample中的run()方法。
1.4.2 继承Thread类创建线程
Thread是一个类,可以直接继承该类来创建线程,使用方法如下。
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-025-2.jpg?sign=1738806011-DaktfWGSctEDqdRkWMCPdblNZs9klQrT-0-3952d25cf2b0de988d6bc0cf5959e20c)
Runnable和Thread的区别在于,前者是接口,后者是类。如果当前需要实现线程的类已经集成了另外一个类,就无法再通过集成Thread类来实现线程,只能通过Runnable接口来完成。
Thread类也实现了Runnable接口,即一个线程实例。启动线程的方法仍然是通过Thread类的start()实例方法来完成的。
1.4.3 实现Callable接口并创建带返回值的线程
在有些场景中,我们可能需要让一个异步执行的任务在执行完成后返回一个结果。而前面使用的线程中,run()方法是一个void修饰的无返回值的方法,很显然无法达到我们的要求。因此在Java中提供了Callable和Future来创建有返回值的线程,实现代码如下。
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-025-3.jpg?sign=1738806011-BZdNdl0JNVfaK8YbLlJK4N9S4d6qsDMN-0-05d3dc25fa196659d0d8e7f1806349a5)
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-026-1.jpg?sign=1738806011-gy9DsDN2Jwd1fszrfSlpjBaoivd16ydZ-0-f2b6a51ebd3d0625035b0cf3062daa8f)
从上述代码中可以看到,Callable接口提供了一个带有返回值的call()方法,接着定义了一个FutureTask,来表示一个获取未来执行结果的任务,并使用Thread线程来执行,最后通过futureTask.get()方法来获得执行结果。
这种方式并不是目前最好的选择,在后续章节中笔者会详细说明它的原理及最佳实践方案。