为什么我们在Java中使用线程?

总而言之,我们使用线程来同时完成多个任务,从而使Java应用程序更快。从技术上讲,Thread可以帮助您在Java程序中实现并行。由于CPU速度非常快,现在它甚至包含多个内核,只有一个线程无法利用所有内核,这意味着昂贵的硬件在大部分时间内都会保持闲置状态。通过使用多个线程,您可以通过为更多客户端提供服务并更快地提供服务来充分利用多个内核。因为在当今快节奏的世界里,响应时间很重要,这就是为什么你有多核CPU的原因,但是如果你的应用程序没有充分利用所有的资源,那么没有必要添加它们,多线程就是一个在Java应用程序中利用CPU的巨大计算能力的方式。

在Java中使用Thread还有另一个目的,可以同时完成多个任务。例如,在GUI应用程序中,您希望在同时绘制屏幕的同时还要捕获用户的操作,例如按键和命令,并且您可能想要从网络下载或上传某些内容。

如果你在一个线程中完成所有这些任务,它们将被顺序执行,即先画出屏幕然后捕获命令,最后将最高分上传到网络。这可能会导致您的游戏或应用程序出现问题,因为在您执行其他任务时,GUI似乎被冻结。通过在Java中使用多个线程,您可以独立执行每个任务。

在Java中使用多线程的原因

即使Java应用程序至少包含一个线程,即执行主方法的主线程。有更多的线程使用JVM,例如守护进程线程,它们执行垃圾回收和其他一些内务工作。作为应用程序开发人员,您还可以添加新的用户线程,使您的应用程序更快,更高效。以下是在Java中使用多个线程的一些常见原因和方案:1)使任务与另一个任务并行运行,例如绘图和事件处理。

GUI应用程序(例如Swing和Java FX GUI)是Java中多线程的最佳示例。在一个典型的GUI应用程序中,用户启动一个动作,例如从网络下载文件或从硬盘加载游戏模块。这些操作需要一些时间才能完成,但不能冻结GUI,因为用户会认为应用程序已挂起。相反,您需要一个单独的线程来执行耗时的任务,并不断向用户显示相关的消息,或者让他同时执行其他任务,以保持GUI活着。这是通过在Java中使用多个线程来实现的。

2)充分利用CPU的能力。
在Java中使用多线程的另一个常见原因是通过利用全部CPU功率来提高应用程序的吞吐量。例如,如果您有32个核心CPU,并且您只使用其中的一个为1000个客户端提供服务,并假设您的应用程序受CPU限制,则可以使用32个线程将吞吐量提高到32倍,这将使用32个内核你的CPU。您可以进一步阅读一本关于Java性能调优书籍的好书,例如“  Java性能权威指南”,   作者为Scott Oaks,以了解更多关于多线程性能影响的内容。

3)为了减少响应时间
您还可以使用多线程通过快速计算来减少响应时间,方法是将大问题分成更小的块并使用多线程处理。例如,map-reduce模式是基于将一个大问题分解为一个小问题并分别处理,Java也为此提供了Fork-Join线程池。


4)同时切断多个客户端。
客户端 - 服务器应用程序是使用多线程显着提高应用程序性能的最常见情况之一。单线程应用程序意味着一次只能有一个客户端连接到服务器,而多线程服务器意味着多个客户端可以同时连接到服务器。这意味着下一个客户端不必等到您的应用程序完成之前客户端的处理请求。

就像在下面的例子中一样,你可以看到多个请求正在被我们的多线程服务器同时处理。


顺便说一句,Threading不是免费的,它有自己的挑战。只能在一定程度上最大限度地提高应用程序的吞吐量,一旦线程编号增加到一定的阈值,它们就会开始竞争CPU,并发生上下文切换。上下文切换意味着正在使用CPU的一个线程被挂起,CPU被分配给另一个线程执行。发生这种情况时,线程通常会丢失所有缓存的数据。如果该线程在另一个核心上恢复,则必须从头开始构建它的缓存。

线程还引入了一个称为多线程问题的特殊问题,例如死锁,活锁,内存不一致错误,竞态条件和饥饿。测试涉及多个线程的Java程序也是非常困难的。无法预测多线程情况下的执行顺序,也无法进行同步。您还应该阅读  Java Concurrency in Practice  以了解更多如何在Java中有效使用线程。



而且,并行性将被限制在关键部分的大小的事实上,即,一次只能由唯一线程执行的代码部分。如果你有一个很长的关键部分,那么最终所有线程都会在那里等待,你的程序就像一个单线程的程序。


这就是为什么在Java中使用线程。使用线程的基本原理与使用多个工作者来完成任务是一样的,但是您必须记住,并不是所有的任务都可以通过部署多个工作者来提前完成,例如,9个母亲在一个月内不能提供一个婴儿。同样,只是创建多个线程,使您的程序更快将无法正常工作。您只能通过将CPU绑定任务划分为多个线程(例如大型计算)来提高性能。如果您的应用程序是IO绑定的,那么您可能需要考虑其他技术,例如更快的硬盘来提高性能。

您还应该考虑与多线程相关的问题,因为处理多线程之间的同步并防止死锁,活锁,饥饿和内存不一致等问题并不容易。通常单线程就是你所需要的,因为它使得编码变得容易,如果你的应用程序是单线程的,你不需要同步任何东西。

我建议你阅读一本关于多线程和设计的好书,例如Java Concurrency in Practice, 


关于“ 为什么我们在Java中使用线程? 的评论

发表评论