![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=1738755380-tJmv7wyxrHzDxfzRZvYwTaN547PvSoqq-0-3c67139aaf4d6f3bbed7d169a1707754)
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-025-1.jpg?sign=1738755380-zRSYPAAzcyeoIUJM5lyEqFq3qsmLx2Ra-0-f606414c114a77342adf70c70b3fec84)
注意:线程是通过thread.start()来启动的,线程启动后,会异步执行RunnableThreadExample中的run()方法。
1.4.2 继承Thread类创建线程
Thread是一个类,可以直接继承该类来创建线程,使用方法如下。
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-025-2.jpg?sign=1738755380-z13v68lpvlMEQjWcHcJ6c7cTES03LnaN-0-6d4905c2a6d34140cadb466a623b7283)
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=1738755380-dhvZdUCgKZOUQZhEfKBSuBW0dCGII4gx-0-5ed2f3606240b3fb97b757edc6a978ec)
![](https://epubservercos.yuewen.com/11B439/23020636309729206/epubprivate/OEBPS/Images/42136-00-026-1.jpg?sign=1738755380-Cyoh34eQyhLAt0lFaPsNgbTK0RVSp9sd-0-0087aa833b641f7a7d351688a4e6286f)
从上述代码中可以看到,Callable接口提供了一个带有返回值的call()方法,接着定义了一个FutureTask,来表示一个获取未来执行结果的任务,并使用Thread线程来执行,最后通过futureTask.get()方法来获得执行结果。
这种方式并不是目前最好的选择,在后续章节中笔者会详细说明它的原理及最佳实践方案。