Java中如何正确的创建线程数量
2019-09-29 本文已影响0人
LssTechnology
问题
java开发中,线程数通常定义为:
线程数 = Runtime.getRuntime().availableProcessors() * 2
, 为什么呢?
前言
在java开发过程中,不可避免的要使用多线程进行开发,那么,我们该如何确定创建线程的数量呢?首先我们先了解几个概念
一、线程和进程的概念
- 线程和进程的区别:
线程是指程序在执行过程中,能够执行程序代码的一个执行单元。在java语言中,线程有四种状态:运行 、就绪、挂起和结束。
进程是指一段正在执行的程序。而线程有时也被成为轻量级的进程,他是程序执行的最小单元,一个进程可以拥有多个线程,各个线程之间共享程序的内功空间(代码段、数据段和堆空间)及一些进程级的资源(例如打开的文件),但是各个线程都拥有自己的棧空间。 - 为何要使用多进程
在操作系统级别上来看主要有以下几个方面:
- 使用多线程可以减少程序的响应时间,如果某个操作和耗时,或者陷入长时间的等待,此时程序将不会响应鼠标和键盘等的操作,使用多线程后可以把这个耗时的线程分配到一个单独的线程去执行,从而使程序具备了更好的交互性。
- 与进程相比,线程创建和切换开销更小,同时多线程在数据共享方面效率非常高。
- 多CPU或者多核计算机本身就具备执行多线程的能力,如果使用单个进程,将无法重复利用计算机资源,造成资源的巨大浪费。在多CPU计算机使用多线程能提高CPU的利用率。
- 使用多线程能简化程序的结构,使程序便于理解和维护
二、线程的定义
- 线程池中线程的个数,在《java虚拟机并发编程》定义为:
线程数 = cpu可用核心数 / (1-阻塞系数)
其中阻塞系数的取值在[0,1]之间。计算密集型任务的阻塞系数为0,而IO密集型任务的阻塞系数则接近1。一般,我们让线程执行的任务是比较复杂的,不会是单一的计算密集型任务,或者单一的IO密集型任务,通常会夹杂着。那么就需要我们去计算阻塞系数了。阻塞系数的定义就是执行该任务阻塞的时间与(阻塞时间+计算时间)的比值,也就是w/(w+c)。
- 计算密集型任务和IO密集型任务
计算密集型任务通常是指需要通过复杂的算法来实现业务逻辑
IO密集型任务通常是指数据库数据交互、文件上传下载、网络数据传输等等
三、java中线程数量创建
1、Java虚拟机可用的处理器数
Runtime.getRuntime().availableProcessors()
/**
* Returns the number of processors available to the Java virtual machine.
*
* <p> This value may change during a particular invocation of the virtual
* machine. Applications that are sensitive to the number of available
* processors should therefore occasionally poll this property and adjust
* their resource usage appropriately. </p>
*
* @return the maximum number of processors available to the virtual
* machine; never smaller than one
* @since 1.4
*/
public native int availableProcessors();
2、阻塞系数计算
- 可以将你的需要执行的任务量化,你需要确定哪些步骤是IO操作,哪些步骤的计算操作,然后跑一次,来确定执行这个任务耗费在IO多少时间,耗费在计算上多少时间,这样算起来比较麻烦。
- 所以对于一般的应用程序来说,每一次任务都少不了IO和任务操作,通常可以把阻塞系数取0.5
最终,我们再java中定义线程数可以取为:
线程数 = Runtime.getRuntime().availableProcessors() * 2