多线程总结

Java里创建线程主要有三种方式:

继承 Thread类:Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线程,并执行 run()方法。

实现 Runnable接口:如果自己的类已经 extends 另一个类,就无法直接 extends Thread,此时,可以实现一个Runnable 接口。

实现 Callable接口:实现Callable接口,重写call()方法,可以返回一个 Future类型的返回值。我在上面的例子里就是用到了这种方式。

线程池的七大核心参数

: 线程池刚创建时,里面没有一个线程,当调用 execute() 方法添加一个任务(创建的线程实例)时,
调用 execute() 方法调度任务,判断是否直接创建核心线程执行任务,或放入到等待队列中,或创建非核心线程执行任务。
核心线程数corePoolSize :线程池刚创建时,里面没有一个线程,当调用 execute() 方法添加一个任务(创建的线程实例)时,如果正在运行的线程数量小于corePoolSize,则马上创建新线程并运行这个任务。计算密集型一般推荐线程池不要过大,一般是CPU数 + 1,IO密集型:线程数适当大一点,机器的Cpu核心数*2。
可以通过调用prestartAllCoreThreads方法一次性的启动corePoolSize个数的线程。当线程数 = corePoolSize时,新任务会追加到workQueue中。

活跃时间keepAliveTime:非核心线程 =(maximumPoolSize - corePoolSize ) ,非核心线程闲置下来不干活最多存活时间。

保持存活时间unit:线程池中非核心线程保持存活的时间

等待队列workQueue:线程池 等待队列,维护着等待执行的Runnable对象。当运行当线程数= corePoolSize时,新的任务会被添加到workQueue中,如果workQueue也满了则尝试用非核心线程执行任务

允许的最大线程数maximumPoolSize:maximumPoolSize表示允许的最大线程数 = (非核心线程数+核心线程数),当BlockingQueue也满了,但线程池中总线程数 < maximumPoolSize时候就会再次创建新的非核心线程(超过活跃时间会被回收)。

线程工厂 threadFactory:创建一个新线程时使用的工厂,可以用来设定线程名、是否为daemon线程等等。

四种拒绝策略

拒绝策略RejectedExecutionHandler:corePoolSize、workQueue、maximumPoolSize都不可用的时候执行的 饱和策略。
1.CallerRunsPolicy - 当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。一般并发比较小,性能要求不高,不允许失败。但是,由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率上必然的损失较大
2.AbortPolicy(默认拒绝策略 ) - 丢弃任务,并抛出拒绝执行 RejectedExecutionException 异常信息。线程池默认的拒绝策略。必须处理好抛出的异常,否则会打断当前的执行流程,影响后续的任务执行。
3.DiscardPolicy - 直接丢弃,其他啥都没有
4.iscardOldestPolicy - 当触发拒绝策略,只要线程池没有关闭的话,丢弃阻塞队列 workQueue 中最老的一个任务,并将新任务加入

常见的等待队列

ArrayBlockingQueue :由数组结构组成的有界阻塞队列。

LinkedBlockingQueue :由链表结构组成的有界阻塞队列。

PriorityBlockingQueue :支持优先级排序的无界阻塞队列。

DelayQueue:使用优先级队列实现的无界阻塞队列。

SynchronousQueue:不存储元素的阻塞队列。

LinkedTransferQueue:由链表结构组成的无界阻塞队列。

LinkedBlockingDeque:由链表结构组成的双向阻塞队列

创建线程池的方式

在这里插入图片描述

FixedThreadPool

定长的线程池,有核心线程,核心线程的即为最大的线程数量,没有非核心线程。

使用的无界的等待队列是LinkedBlockingQueue。使用时候有堵满等待队列的风险。
在这里插入图片描述

SingleThreadPool

只有一条线程来执行任务,适用于有顺序的任务的应用场景,也是用的无界等待队列
在这里插入图片描述

CachedThreadPool

可缓存的线程池,该线程池中没有核心线程,非核心线程的数量为Integer.max_value,就是无限大,当有需要时创建线程来执行任务,没有需要时回收线程,适用于耗时少,任务量大的情况。任务队列用的是SynchronousQueue如果生产多快消费慢,则会导致创建很多线程需注意。

在这里插入图片描述

ScheduledThreadPoolExecutor

周期性执行任务的线程池,按照某种特定的计划执行线程中的任务,有核心线程,但也有非核心线程,非核心线程的大小也为无限大。适用于执行周期性的任务。

看构造函数:调用的还是ThreadPoolExecutor构造函数,区别不同点在于任务队列是用的DelayedWorkQueue。

在这里插入图片描述

参考链接: 多线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值