何时适合使用多线程?

8 浏览
0 Comments

何时适合使用多线程?

我认为我对Java的多线程基本原理有所了解。如果我没记错的话,你需要将一个大任务分割成多个(并发的)子任务。然后你将这些子任务实现为RunnableCallable,并将它们全部提交给ExecutorService。(所以,首先,如果我在这方面有任何错误,请纠正我!!!)

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

但是,我在Java并发编程(以及一般的并发编程)中仍然遇到的真正问题,也是这个问题的真正主题是:

什么时候才适合使用多线程?

我在Stack Overflow上看到一个问题的例子,其中提问者提议为读取和处理一个巨大的文本文件(《白鲸记》)创建多个线程,然后一个回答者评论说,为了从磁盘读取而使用多线程是一个糟糕的主意。他们的理由是因为你会有多个线程引入上下文切换的开销,而这本身就是一个很慢的过程(磁盘访问)。

这让我想:什么类别的问题适合使用多线程,什么类别的问题应该始终串行化?谢谢!

0
0 Comments

多线程适用于CPU密集型任务,如内存中的排序等需要大量数据处理的任务。而I/O绑定任务,如磁盘I/O,则应该保持串行执行。这是一般性的建议,当然也有一些例外情况。

在这里,有人提出了一个问题,即什么样的问题适合使用多线程,什么样的问题应该始终保持串行执行。

有人对此进行了进一步解释,解释了最大化IO通道和I/O“绑定”之间的区别。如果你在等待远程发送方发送I/O并在顺序程序中被限制,那么网络I/O程序应该使用多线程。

这个问题引起了大家的共鸣。虽然文章的作者本打算在晚餐后更新一些例子,但他看到大部分问题已经被讨论过了。

可以得出结论:问题的并行化取决于任务的性质,如CPU密集型还是I/O绑定型。在选择是否使用多线程时,需要考虑任务的特点以及可能的例外情况。

0
0 Comments

当构建使用Swing组件的GUI时,有时候点击按钮执行的任务会花费很长时间,这样在执行任务期间会锁定GUI界面。为了保持GUI界面的响应性,可以将任务放在不同的线程中执行,保持GUI线程(Swing worker线程)对Swing组件的响应。


// Example code for executing a task in a separate thread
SwingWorker worker = new SwingWorker() {
    @Override
    protected Void doInBackground() throws Exception {
        // Perform long-running task here
        return null;
    }
    
    @Override
    protected void done() {
        // Update GUI components or perform any other necessary actions
    }
};
worker.execute(); // Start the task in a separate thread

There are certain classes of problems that are appropriate for multi-threading. For example, when performing computationally intensive tasks such as image or video processing, multi-threading can significantly improve the performance by utilizing multiple cores of the CPU. By dividing the task into smaller sub-tasks and executing them in parallel, the overall processing time can be reduced.

On the other hand, there are also classes of problems that should always be serialized. For instance, when accessing shared resources or modifying data structures that are not thread-safe, it is crucial to ensure that only one thread at a time can access or modify them to avoid data corruption or race conditions.

To determine whether multi-threading is appropriate for a specific problem, it is essential to consider factors such as the nature of the task, the availability of multiple cores, the complexity of synchronization and coordination between threads, and the impact on overall performance.

In conclusion, multi-threading is appropriate for tasks that can be parallelized and do not require extensive synchronization or access to shared resources. Utilizing multi-threading can improve performance and responsiveness in certain scenarios. However, it is crucial to carefully consider the potential issues and challenges associated with multi-threading, such as race conditions and data corruption, and implement proper synchronization mechanisms to ensure thread safety.

0
0 Comments

在什么情况下适合使用多线程?

多线程有两个主要优点:

1. 能够将密集型工作分布到多个CPU/核心上:而不是让3个CPU闲置,只在一个CPU上执行所有任务,可以将问题分成4个部分,让每个CPU分别处理自己的部分。这减少了执行CPU密集型任务所需的时间,并且证明了你在多CPU硬件上花的钱是值得的。

2. 减少许多任务的延迟。假设有4个用户向Web服务器发出请求,并且所有请求都由单个线程处理。假设第一个请求进行了非常长的数据库查询。线程处于空闲状态,等待查询完成,而其他3个用户则等待直到此请求完成才获取他们的小型网页。如果有4个线程,即使只有一个CPU,第二、三和四个请求也可以在长时间的数据库查询由数据库服务器执行时处理,并且所有用户都很满意。因此,当存在阻塞IO调用时,多线程特别重要,因为这些阻塞IO调用让CPU处于空闲状态,而不是执行其他等待任务。

请注意:从多个线程从同一磁盘读取的问题在于,它会强制磁盘在每次上下文切换时在磁盘的不同物理位置之间切换。由于所有线程都在等待磁盘读取完成(它们是IO限制),这使得读取速度比单个线程读取所有内容要慢。但是,一旦数据在内存中,将工作分配给线程是有意义的。

当数据库API在I/O中阻塞而数据库繁忙时,你是不是讨厌呢?谢谢,但是我有其他有用的事情可以让该线程在你处理它时执行...(几乎和网络名称解析一样糟糕,非DNS方案的遗留使整个混乱变得糟糕。)

磁盘操作-请注意,如果从磁盘上的多个小文件读取,每个线程都有自己的文件要读取,线程的访问允许磁盘I/O系统进行优化-它可以首先为请求该文件的线程提供物理上最近的文件,使该线程准备/运行,然后继续处理下一个最近的未完成磁盘请求。

实际上,我喜欢这个。传统的顺序程序比基于事件的异步程序更容易实现、理解和维护。当然,它们需要多线程,但是应用服务器为我处理了这一切。像Node.js这样的异步系统有它们的用途,但是在我看来,它们只在非常特定的用例中有用,其中并发用户数量庞大。

0