我一直在我的软件中使用多线程。然而令我困惑的是,多线程如何提高应用程序的性能?据我所知,操作系统为进程/应用程序分配了一个线程。如果在该进程中创建多个线程,那么这些线程就不像是由OS分配给进程的全新线程。相反,一个线程一次执行而另一个线程正在等待。我可能错了,因此我想澄清这种困惑。
关于非UI线程的示例& UI线程将非常有用。
修改
我接受它,只要我没有通过Mainthread代替runnable,Handler的实例将创建一个新的单独的UI线程,无论是否与mainUI线程上的/ puts负载相关,Right ?
// executes code on mainUI thread thread?
new Handler(Looper.getMainLooper()).post(){
....
}
// creates a separate UI thread that isn't related to/executes code on mainUI thread at all, Correct?
new Handler(new Runnable()).post(){
....
}
答案 0 :(得分:5)
多线程如何提高应用的性能?
一般来说,它不会提高应用的性能。它可以解决用户体验方面的具体问题,例如减少jank。
据我所知,操作系统为进程/应用程序分配了一个线程。
不,一个Android应用程序将在一开始就有多个线程,由框架创建。这些包括主应用程序线程和绑定程序线程池。
如果在该进程中创建多个线程,那些线程就不像操作系统分配给该进程的全新线程一样。
是的,他们是。
而是在另一个线程正在等待时,一次执行一个线程。
在多核CPU上,多个线程可以真正并行执行。即使在单核CPU上,Linux调度程序(Android核心的Linux内核的一部分)也会在线程之间进行时间分割。
关于非UI线程的示例& UI线程将非常有用。
主要的应用程序线程(a.k.a.,UI线程)的核心只是一个线程。但是,它是负责调度键和触摸事件以及以其他方式应用UI更新的线程。重要的是不要阻止该线程,因此如果您正在该线程上运行(例如,onCreate()
的活动和片段,onClick()
的小部件,getView()
在{{1}你需要非常快速地返回 ,理想情况下是在毫秒之内。否则,你有" jank",在Android中被定义为冻结的UI,特别是在UI应该是动画时(例如,滚动ListAdapter
)。
因此,例如,让我们假设我们要下载一个文件,一个足够大,下载需要10秒。我们是在主应用程序线程上还是在后台线程上下载文件不会影响整体性能,因为无论哪种方式都需要10秒。但是,在主应用程序线程上下载会冻结我们的UI 10秒钟,这将使用户不满意。在后台线程上下载文件可以避免此问题。请注意,默认情况下,尝试在主应用程序线程上执行网络I / O会在Android 4.0+(带ListView
)时失败,特别是为了避免此特定问题。
答案 1 :(得分:1)
主题和进程不一样。 (见最后的链接)
如果您的设备具有单个进程(单核),则线程将不会并行运行,但它们将重复切换执行,这将由OS /编译器管理。
但如果您的设备是多处理器(多核),则线程将在不同的核心上并行执行。在这里,程序员必须非常小心race condition / synchronization issues。
因此,简单来说,线程将负担从一个核心分割到多个核心,这就是线程如何提高性能。
除了线程之外,一般来说,编译器的工作是识别独立的代码语句序列并在不同的内核上并行运行,以获得最大的性能(速度)。因此,开发人员也可以编写代码,以便可以在多个内核上并行执行。
如果您对线程和并发感兴趣,请参阅此本书,它涵盖了各个方面(Java和Clojure)Seven concurrency models in seven weeks
What is the difference between a process and a thread?
http://www.programmerinterview.com/index.php/operating-systems/thread-vs-process/
答案 2 :(得分:0)
您可以在多核中使用线程/池执行程序并行运行线程,工作线程用于在后台执行某些工作,这可能会也可能不会将数据发送到主线程以更新UX。例如,在列表视图中,如果不使用单独的/工作线程而不是主线程将阻止,则每行都有拇指图像。虽然对于每一行的拇指,我们使用并行线程下载图像并显示在相应的行中,现在工作线程负责下载拇指,这可能需要几秒钟,在下载之后,该线程将图像返回到主线程,现在将图像设置为其指定的位置。