为什么要使用java线程池

线程池

java中线程的机制:

1、java中线程的执行是抢占式执行,哪个线程抢到,在规定的时间(java有规定的时间片),就是这个线程执行,执行结束(也就是时间片),就进入就绪状态(java中其实没有就绪状态和运行时状态的说法,规范统一都是runnable状态,为了让大家好理解才说就绪和运行时状态)。
2、在多线程多任务的情况下,需要创建多个线程,同时最后也会有多个线程的“死亡”(线程的创建和死亡也是需要时间的:)

暴露出来的问题:

1,多任务执行的时候,线程的不断创建,不断关闭,就会过度的消耗cpu资源
2、线程一多,频繁的切换线程,可能会导致系统崩溃
3、总通俗的话来解释上面:就是以传统的多线程执行任务,多少个任务就会创建多少个线程,同时到最后结束的时候,就会有多少个线程死亡,(假如:某个任务执行的时间为很短,短如10ms,那么便会为了10ms创建专门一个线程,这显然是不合理的,又占用cpu资源)
4、因此线程池就是为了解决以上暴露的问题而出来的。

什么是线程池

1、线程池:顾名思义:存放线程的池子,就尼玛的这么通俗易懂。
线程池的使用:将作业任务放到队列里面,线程池里面的空闲资源会去执行队列里面的任务。执行完毕之后线程再次空闲(“非核心线程存活是有时间的哦”)
线程池里面的线程
:两类:
核心线程:

  • 1、在线程池创建的时候就已经创建了
  • 2、即使所有任务执行完毕,也不会销毁(直到虚拟机关闭或者手动关掉线程池,线程才会销毁)
  • 3、其数量由线程池的实现类确定,也可以自己写一个线程池(也称之为自定义线程池)

非核心线程:

  • 1、在线程创建的时候不会创建,而是当核心线程都不空闲,而任务需要执行,才会创建
  • 2、其数量由线程池的实现类确定
  • 3、其存活时间由线程池的实现类确定。

一个简单的自定义线程池:
先上代码,再解释:

package 博客.线程池;


import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Application {
	public static void main(String[] args) {
		// 自定义线程池
		ThreadPoolExecutor pool = new ThreadPoolExecutor(8,12,1,TimeUnit.SECONDS,new ArrayBlockingQueue(10));
//		pool.execute(() -> {
//			System.out.println("自定义线程池");
//		});
		pool.execute(new Runnable() {	
			@Override
			public void run() {
				System.out.println("自定义线程池");
			}
		});
	}
}

运行结果:
在这里插入图片描述分析:
运行结果来看:虚拟机并没有被关闭,也就意味着,还有线程存活着
第一步分析:

ThreadPoolExecutor pool = new ThreadPoolExecutor(8,12,1,TimeUnit.SECONDS,new ArrayBlockingQueue(10));

表示的是自定义线程池:核心线程:8非核心线程::最多可以创建:12-8=4个,非核心线程最多存活的时间为:1分钟,所用的数组是ArrayBlockingQueue(10)):
因为核心线程不死原则(pool关闭之前)以及非核心线程没有任务之后一分钟才死亡原则,所以虚拟机没有关闭

第二步分析:
为什么要使用线程池呢?
1、以上一个例子线程池为例:当任务进入线程池,
|—任务先交给空闲的核心线程
|—核心线程执行完毕,又进入空闲状态,等待下一个任务的到来
|—如果多任务进来,核心线程不够用,便会创建非核心线程,分担核心线程的压力,但是非核心线程数和空闲最长时间由我们掌控
这样做的好处1、:由于线程数由我们掌控,避免了过多线程的创建
2:由于线程执行任务完毕之后,不会死亡,而是等待下一个任务的到来,避免了过多线程的创建,也避免了线程的过快创建和过快死亡(降低了线程的死亡和创建给cpu带来的压力)

在我们的使用中,我们不需要一般不需要自定义线程池

1根据实际需求选择合适的线程池就ok了
创建线程池:需要用到Executes这个类

  • Executes.newCachedThreadPool ():
    没有核心线程,只有非核心先吃,线程空闲存活时间为一分钟
    应用场景:任务过多且需要不断创建线程的时候

  • Executes.newFixedThreadPool(int a)
    只有核心线程:必须传入一个数值
    可以控制最大并发数,防止创建过多的线程

  • Executes.newSingleThreadExecutor()
    只有一个线程,且是核心线程
    这样确定了任务的执行顺序。

  • Executes. newScheduledThreadPool ()(挺重要的,在项目开发的时候常用)
    指定核心线程数,也只有核心线程
    这个线程池和上面有点不同,父类引用是ScheduledExecutorService
    由于父类引用的差异性:多出了以下两种功能
    1、延迟执行
    2、指定周期执行

延迟执行

调用的执行方法不是	execute()了,而是scheduleAtFixedRate(Runnable , int ,TimeUtile)
所以可以延迟时间执行

指定周期执行:

scheduleAtFixedRate(Runnable对象,2,1,TimeUtile.SECONDS)
表示的是:延迟两秒执行,
没隔一秒执行一次

最后:

希望这篇博客能对各位朋友有用,有什么问题请即使提出,谢谢

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值