Java 什么时候适合多线程?

Java 什么时候适合多线程?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我想我已经掌握了Java多线程的基本知识。如果我没弄错的话,你需要做一些大的工作,并弄清楚如何将其分为多个(并发)任务。然后将这些任务实现为Runnables或Callables,并将它们全部提交给ExecutorService。(因此,首先,如果我在这一点上错了,请先纠正我!!!) 其次,我必须设想,您在run()或call()中实现的代码必须尽可能“并行化”,使用非阻塞算法等,而这正是难点所在(编写并行代码)正确吗?不正确? 但是Java并发性(我想一般来说是并发性)仍然存在的真正问题是,这

我想我已经掌握了Java多线程的基本知识。如果我没弄错的话,你需要做一些大的工作,并弄清楚如何将其分为多个(并发)任务。然后将这些任务实现为
Runnable
s或
Callable
s,并将它们全部提交给
ExecutorService
。(因此,首先,如果我在这一点上错了,请先纠正我!!!

其次,我必须设想,您在
run()
call()
中实现的代码必须尽可能“并行化”,使用非阻塞算法等,而这正是难点所在(编写并行代码)正确吗?不正确?

但是Java并发性(我想一般来说是并发性)仍然存在的真正问题是,这是这个问题的真正主题:

什么时候最适合使用多线程

我在另一个关于堆栈溢出的问题中看到了一个例子,海报建议创建多线程来读取和处理一个巨大的文本文件(Moby Dick一书),一位回答者评论说,多线程从磁盘读取是一个糟糕的主意。他们的理由是,在一个已经很慢的进程(磁盘访问)之上,有多个线程引入了上下文切换的开销

这让我想到:什么类型的问题适合多线程,什么类型的问题应该总是序列化?提前感谢

这让我思考:什么类型的问题适合 多线程,什么类型的问题应该总是序列化

基本上,CPU密集型任务(例如,执行大量数据处理,如内存排序)应该并行化(如果可能),I/O绑定的任务应该保持顺序(如磁盘I/O)。这是一般性的建议,当然也有例外

这让我思考:什么类的问题适合多线程,什么类的问题应该总是序列化

当您使用Swing组件构建GUI时,有时您希望通过单击按钮(例如)来完成的任务会花费很长时间,以至于在执行任务时会锁定GUI


因此,您可以在不同的线程中执行任务,这样您就可以使GUI线程(Swing worker线程)对Swing组件做出响应。

多线程对于:

  • 跨多个CPU或多个内核分发工作
  • 在执行冗长的任务(例如加载文件、执行计算)时保持响应
  • 在执行可能阻塞的操作(例如,从插座读取)时保持响应

依我看,多线程有两个主要优点:

  • 能够跨多个CPU/内核分配密集型工作:不要让4个CPU中的3个闲置,在单个CPU上完成所有工作,而是将问题分为4个部分,让每个CPU独立工作。这减少了执行CPU密集型任务所需的时间,并证明了您在多CPU硬件上花费的资金是合理的
  • 减少许多任务的延迟。假设有4个用户向web服务器发出请求,请求都由一个线程处理。假设第一个请求进行了很长的数据库查询。线程处于空闲状态,等待查询完成,其他3个用户等待该请求完成,以获取他们的小网页。如果有4个线程,即使只有一个CPU,第二个、第三个和第四个请求也可以在数据库服务器执行长数据库查询时处理,所有用户都很满意。因此,当您有阻塞IO调用时,多线程尤其重要,因为那些阻塞IO调用会让CPU空闲,而不是执行其他等待的任务

注意:从多个线程读取同一磁盘的问题是,它不会顺序读取整个长文件,而是会迫使磁盘在每个上下文切换时在磁盘的不同物理位置之间切换。由于所有线程都在等待磁盘读取完成(它们是IO绑定的),这使得读取速度比单个线程读取所有内容时慢。但是,一旦数据进入内存,在线程之间分割工作是有意义的。

我更喜欢这种方式

  • 线程在基于GUI的应用程序中非常重要。

  • 在Java中,GUI由事件调度器线程处理始终建议保持 UI线程上的UI工作,以及非UI线程上的非UI工作。 假设您按下一个按钮,然后向某个Web服务器发出一个http请求,在服务器上进行处理,然后服务器返回结果如果您不创建非UI线程来处理此作业,那么您的GUI将是非响应的,直到收到Web服务器的响应为止。

  • 线程在同时执行多个工作的情况下也非常重要。 最好的例子是OS。通常,我会一边听我最喜欢的音乐,一边上网,等等。。。。这就是多线程非常方便的地方,如果只有一个线程的话,我们将永远不会想象我们今天可以用操作系统做什么

  • 跨CPU的多线程用于CPU密集型工作的并行处理

  • Java Servlet的情况下,命中服务器的每个请求都将由容器提供的一个单独线程处理。


  • 并发在某些算法中也非常有用。例如,我目前正在编写一个程序,计算复杂pr的最佳解决方案