JAVA基础进阶(十一)

本文详细介绍了Java中创建线程的三种方式,包括继承Thread类、实现Runnable接口以及使用线程池。讨论了线程安全问题和线程池的使用,重点讲解了线程池的创建参数、执行流程、拒绝策略以及进程与线程的关系。
摘要由CSDN通过智能技术生成

一、创建线程的三种方式

Java语言中是用Thread类来表示线程,线程的创建和开启都是通过Thread类来实现的

继承Thread类重写run方法。

调用线程对象的start()方法启动线程(启动后还是执行run方法的),而不是调用创建的子类对象的run()方法。

可以使用匿名内部类创建Runnable接口的线程

具体这三种线程的创建可以看idea中的代码,已经都敲过了

二、3种创建线程方式的对比

三、线程Thread类的常用API

四、线程的安全问题

多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题(对共享资源进行增删改操作)。

五、线程池的创建、使用、参数

5.1线程池的作用

线程池的作用:线程池就是一个可以复用线程的技术

例如:不使用线程池的情况下,10个请求我就要创建10个线程,并且使用完后还要销毁这些线程。使用线程池后,我只创建3个线程,再这3个线程处理完当前线程后,就会处理任务队列中剩下的线程,并且核心线程是不会被销毁的,会一直存在。(这里3个线程是随便写的,不是具体算出来的)。

线程过多会占用CPU、内存等资源,所以使用线程池后,会缓解这些现象的发生。

5.2 线程池的7个参数

5.3创建线程池的方式

2、使用ThreadPoolExecutor创建线程池(阿里规范中只能使用这个)

ArrayBlockingQueue<>(5):任务队列数量为5

LinkedBlockingQueue<>():任务队列数量无穷,可以存放无数个任务。

2、使用Executors工具类创建线程池。

5.4 线程池的执行流程

语言描述: 某某公司分部(threadFactory)为客户办理业务,一共有4个柜员(maximumPoolSize),不忙的时段就分配2个柜员(corePoolSize)办理业务,剩余2人休息。摆了4个椅子(workQueue),供客户进行等待。并且这个公司给员工定了个规定,就是当工作区的柜员都在工作,并且等待区的座位都做满时,那么处于休息区的柜员要出来帮忙。直到所有柜员都在工作,等待区也坐满了。那为了我们公司员工身体的考虑,暂时拒绝任何人来办理业务(handler),如果有某个员工空闲下来并且超过了10(keepAliveTime)分钟(unit),那就可以回到休息区休息,但是必须保证有2个柜员在工作区。

5.5 线程池的拒绝策略

5.5 线程池处理Runnable任务

线程池处理Runnable任务是使用execute方法。ThreadPoolExecutor中的execute方法:

  1. 线程池会创建线程并调用线程中的run方法
  2. execute方法中需要的参数是Runnable接口的实现类
  3. 这种方法和submit方法最大的区别是没有返回值

创建Runnable接口的实现类MyRunnable,具体的代码如下:

其中Thread.sleep(Integer.MAX_VALUE),是为了让线程一直执行,这样就不会执行完之后去执行后面的线程。

创建一个线程池,核心线程数为3,最大线程数为5,队列中可存放的线程数量为2。

使用execute方法创建3个线程任务:

此时会创建3个线程。

使用execute方法创建5个线程任务:

核心线程数为3,所以还是创建3个线程。剩下的2个线程任务放入任务队列中。

使用execute方法创建7个线程任务:

核心线程数为3,所以还是创建3个线程。2个线程任务放入任务队列中。剩下的2个线程任务由创建的2个临时线程执行。

使用execute方法创建8个线程任务:

核心线程数为3,所以还是创建3个线程。2个线程任务放入任务队列中。剩下的2个线程任务由创建的2个临时线程执行。最后的一个线程任务会直接触发拒绝策略。

上面演示execute方法创建线程的过程正好验证了5.4中线程池的执行流程。

5.6 线程池处理Callable任务

线程池处理Callable任务是使用submit方法。ThreadPoolExecutor中的submit方法:

  1. 返回值类型为Future
  2. 通过get方法获得具体的返回值

六、进程和线程的关系

进程是程序的一个执行实例,是正在执行的程序一个进程可以包括多个线程。下面展示的就是多个进程,每个进程里面又包含多个线程。例如开启一个百度网盘,百度网盘这个进程中就可以包括下载线程和传输线程等。

七、物理CPU、核心数、逻辑处理器之间的关系

首先,需要知道的是:

1、物理CPU数就是主板上实际插入的CPU数量。

2、CPU的核心数是指物理上,也就是硬件上存在着几个核心。比如,双核就是包括2个相对独立的CPU核心单元组,四核就包含4个相对独立的CPU核心单元组。

3、总核数 = 物理CPU个数 × 每颗物理CPU的核数

4、总逻辑CPU数(总逻辑处理器数) = 物理CPU个数 × 每颗物理CPU的核数 × 超线程数

7.1、查看物理CPU的个数

cmd命令中输入“systeminfo”,以下信息表示物理CPU1

7.2、查看CPU核心数、线程数

cmd命令中输入“wmic”,然后在出现的新窗口中输入“cpu get *”

NumberOfCores:表示CPU核心数

NumberOfLogicalProcessors:表示CPU线程数

这里的CPU线程数和任务管理器中CPU的逻辑处理器是一样的,表示在某个瞬间CPU能同时并行处理的任务数。

对应任务管理器中的CPU的内核数和逻辑处理器

逻辑处理器表示CPU能同时处理线程的个数,所以CPU能同时处理20个线程。

上面的结果表明CPU是14核20线程的,说明CPU包含14个相对独立的CPU核心单元组,能在某一时刻同时处理20个线程。

为什么是20个线程而不是28个线程呢?

i5 13600K采用的是混合架构,大小核设计,由6个性能核+8个能效核混合架构组成导致的,其中性能核支持超线程,而能效核转不支持超线程。性能核通过超线程技术,1个核心可以对应两个线程,也就是说它可以同时运行两个线程,所以6个性能核对应12个线程,最终12+8得出来20个线程,而不是28个线程。

参考地址:

Windows下查看电脑的CPU个数,核心数,线程数_如何查看电脑核心数-CSDN博客

https://www.cnblogs.com/fetty/p/8580583.html

八、 并发、并行的概念

并发:CPU会轮询为系统的每个线程服务,由于CPU切换的速度很快,给我们感觉这些线程在同时执行,这就是并发。

这些线程并不是同时执行,而是由于CPU的切换速度很快,给人感觉像是在同时执行。例如之前介绍的CPU是14核20线程,

这个CPU最多能同时执行20个线程,CPU就会轮询的执行例如前20个线程,再执行后面的20个线程,再执行前面20个线程,给人感觉这40个线程像是在同一时刻执行。

并行:在同一个时刻上,同时有多个线程在被CPU处理并执行。这里指的是实际被同时执行的线程,例如之前介绍的CPU是14核20线程,这个CPU最多能同时执行20个线程,所以在同一时刻,最多同时有20个线程被CPU处理并执行。

总结:

并发:CPU分时轮询的执行线程。

并行:同一个时刻同时在执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值