在Java中,更具体地说,Android是新的Threads自动分配给不同于我目前正在使用的CPU核心,或者我应该处理它?
在Java中,线程只是单独的执行序列,但在Android中它比这更复杂。 Android为每个应用程序创建一个主线程。 该主线程负责UI和与事件(队列)相关的其他任务。 要进行后台工作,您必须创建单独的工作线程。
简单线程由Android操作系统自动处理,它们可能会也可能不会在不同的核心上运行 。 如果您运行10个线程,它们很可能都在一个核心上运行,而所有其他核心都处于空闲状态。
如果你需要运行多个线程,并且你想在一个单独的核心上运行每个线程,你应该使用ThreadPoolExecutor ; 它将处理线程创建并将其映射到可用的CPU核心数量上。 您可以根据需要设置各种参数。 看看Android的意思:
ThreadPoolExecutor将根据corePoolSize(请参阅getCorePoolSize())和maximumPoolSize(请参阅getMaximumPoolSize())设置的边界自动调整池大小(请参阅getPoolSize())。 当在方法execute(Runnable)中提交新任务时,并且运行的线程少于corePoolSize线程,即使其他工作线程处于空闲状态,也会创建一个新线程来处理该请求。 如果有多个corePoolSize但运行的maximumPoolSize线程少于maximumPoolSize,则只有在队列已满时才会创建新线程。
有关详细信息,请参见ThreadPoolExecutor 。
是否创建新线程,使用Thread类或将Runnable提交给Executor,是否支持线程池?
是的,请参阅上面的答案。
更新
通过说“在一个单独的核心上运行每个线程使用ThreadPoolExecutor”,我的意思是ThreadPoolExecutor可以做到这一点,如果它以谨慎的方式正确使用。
Java不直接在CPU上映射线程。 Java在操作系统上留下线程调度(通过映射到操作系统的进程),但我们如何创建线程会影响操作系统级别的调度 。 但是,Java可以为线程分配优先级,但是再次由操作系统来支持这些优先级。
在创建线程池时我们应该考虑各种参数,很少如下:
i)线程的复杂程度应相同。
ii)将CPU绑定任务与I / O绑定进行比较,I / O绑定任务通常需要比可用内核更多的线程,以实现CPU的最佳利用
iii)线程之间的依赖性负面影响
如果创建线程时要记住这些要点, ThreadPoolExecutor可以帮助实现100%的CPU利用率,这意味着每个核心有一个线程(如果线程池的大小等于核心数且没有其他线程正在运行)。 ThreadPoolExecutor一个好处是,与单独创建线程相比,它具有成本效益,并且还消除了浪费大量CPU周期的上下文切换。
在实现并发的同时实现100%的CPU利用率并非易事。