Java 什么时候适合多线程?
我想我已经掌握了Java多线程的基本知识。如果我没弄错的话,你需要做一些大的工作,并弄清楚如何将其分为多个(并发)任务。然后将这些任务实现为Java 什么时候适合多线程?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我想我已经掌握了Java多线程的基本知识。如果我没弄错的话,你需要做一些大的工作,并弄清楚如何将其分为多个(并发)任务。然后将这些任务实现为Runnables或Callables,并将它们全部提交给ExecutorService。(因此,首先,如果我在这一点上错了,请先纠正我!!!) 其次,我必须设想,您在run()或call()中实现的代码必须尽可能“并行化”,使用非阻塞算法等,而这正是难点所在(编写并行代码)正确吗?不正确? 但是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绑定的),这使得读取速度比单个线程读取所有内容时慢。但是,一旦数据进入内存,在线程之间分割工作是有意义的。我更喜欢这种方式
并发在某些算法中也非常有用。例如,我目前正在编写一个程序,计算复杂pr的最佳解决方案