java中什么是线程数_Java中如何正确的创建线程数量

问题

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.

*

*

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.

*

* @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

希望对你有所帮助

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring框架,我们可以通过`ThreadPoolTaskExecutor`来创建线程池。要获取`ThreadPoolTaskExecutor`线程数量,可以使用`ThreadPoolTaskExecutor`类的`getActiveCount()`方法来获取当前线程正在执行任务的线程数量,再使用`ThreadPoolTaskExecutor`类的`getPoolSize()`方法来获取当前线程线程。示例代码如下: ```java import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; public class CustomThreadPool { public static void main(String[] args) { // 创建线程池 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); executor.setMaxPoolSize(4); executor.setQueueCapacity(10); executor.initialize(); // 提交任务 for (int i = 0; i < 6; i++) { executor.execute(new Task(i)); } // 获取线程正在执行任务的线程数量 int activeCount = executor.getActiveCount(); System.out.println("当前线程正在执行任务的线程数量:" + activeCount); // 获取线程线程 int poolSize = executor.getPoolSize(); System.out.println("当前线程线程:" + poolSize); // 关闭线程池 executor.shutdown(); } } class Task implements Runnable { private int taskId; public Task(int taskId) { this.taskId = taskId; } @Override public void run() { System.out.println("任务 " + taskId + " 正在执行..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务 " + taskId + " 执行完成!"); } } ``` 上述代码,`CustomThreadPool`类创建了一个`ThreadPoolTaskExecutor`线程池`executor`,并提交了6个任务。然后使用`executor.getActiveCount()`方法和`executor.getPoolSize()`方法获取当前线程线程数量信息,并打印输出。最后关闭线程池。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值