您好,欢迎访问一九零五行业门户网

Java自带的四种线程池是什么?

java预定义的哪四种线程池?newsinglethreadexexcutor:单线程数的线程池(核心线程数=最大线程数=1)
newfixedthreadpool:固定线程数的线程池(核心线程数=最大线程数=自定义)
newcachethreadpool:可缓存的线程池(核心线程数=0,最大线程数=integer.max_value)
newscheduledthreadpool:支持定时或周期任务的线程池(核心线程数=自定义,最大线程数=integer.max_value)
四种线程池有什么区别?上面四种线程池类都继承threadpoolexecutor,在创建时都是直接返回new threadpoolexecutor(参数),它们的区别是定义的threadpoolexecutor(参数)中参数不同,而threadpoolexecutor又继承executorservice接口类
newfixedthreadpool
定义:
xecutorservice executorservice=executors.newfixedthreadpool(2);
缺点:使用了linkblockqueue的链表型阻塞队列,当任务的堆积速度大于处理速度时,容易堆积任务而导致oom内存溢出
newsinglethreadexecutor
定义:executorservice executorservice =executors.newsinglethreadexecutor();
上面代码神似new fixedthreadpoop(1),但又有区别,因为外面多了一层finalizabledelegatedexecutorservice,其作用:
可知,fixedexecutorservice的本质是threadpoolexecutor,所以fixedexecutorservice可以强转成threadpoolexecutor,但singleexecutorservice与threadpoolexecutor无任何关系,所以强转失败,故newsinglethreadexecutor()被创建后,无法再修改其线程池参数,真正地做到single单个线程。
缺点:使用了linkblockqueue的链表型阻塞队列,当任务的堆积速度大于处理速度时,容易堆积任务而导致oom内存溢出
newcachethreadpool
定义:executorservice executorservice=executors.newcachethreadpool();
缺点:synchronousqueue是blockingqueue的一种实现,它也是一个队列,因为最大线程数为integer.max_value,所有当线程过多时容易oom内存溢出
scheduledthreadpool
定义:executorservice executorservice=executors.newscheduledthreadpool(2);
源码:public static scheduledexecutorservice newscheduledthreadpool(int corepoolsize) { //scheduledthreadpoolexecutor继承threadpoolexecutor return new scheduledthreadpoolexecutor(corepoolsize); } public scheduledthreadpoolexecutor(int corepoolsize) { //scheduledthreadpoolexecutor继承threadpoolexecutor,故super()会调用threadpoolexecutor的构造函数初始化并返回一个threadpoolexecutor,而threadpoolexecutor使实现executorservice接口的 //最终scheduledthreadpoolexecutor也和上面几种线程池一样返回的是executorservice接口的实现类threadpoolexecutor super(corepoolsize, integer.max_value, 0, nanoseconds, new delayedworkqueue());}
线程池有哪几个重要参数?threadpoolexecutor构造方法如下:
keepalivetime是指当前线程数位于 [核心线程数,最大线程数] 之间的这些非核心线程等待多久空闲时间而没有活干时,就退出线程池;
等待丢列的大小与最大线程数是没有任何关系的,线程创建优先级=核心线程 > 阻塞队列 > 扩容的线程(当前核心线程数小于最大线程数时才能扩容线程)
假如核心线程数5,等待队列长度为3,最大线程数10:当线程数不断在增加时,先创建5个核心线程,核心线程数满了再把线程丢进等待丢列,等待队列满了(3个线程),此时会比较最大线程数(只有等待丢列满了最大线程数才能出场),还可以继续创建2个线程(5+3+2),若线程数超过了最大线程数,则执行拒绝策略;
假如核心线程数5,等待队列长度为3,最大线程数7:当线程数不断在增加时,先创建5个核心线程,核心线程数满了再把线程丢进等待丢列,当等待队列中有2个线程时达到了最大线程数(5+2=7),但是等待丢列还没满所以不用管最大线程数,直到等待丢列满了(3个阻塞线程),此时会比较最大线程数(只有等待丢列满了最大线程数才能出场),此时核心+等待丢列=5+3=8>7=最大线程数,即已经达到最大线程数了,则执行拒绝策略;
如果把等待丢列设置为linkedblockingqueue无界丢列,这个丢列是无限大的,就永远不会走到判断最大线程数那一步了
如何自定义线程池可以使用有界队列,自定义线程创建工厂threadfactory和拒绝策略handler来自定义线程池
public class threadtest { public static void main(string[] args) throws interruptedexception, ioexception { int corepoolsize = 2; int maximumpoolsize = 4; long keepalivetime = 10; timeunit unit = timeunit.seconds; blockingqueue<runnable> workqueue = new arrayblockingqueue<>(2); threadfactory threadfactory = new nametreadfactory(); rejectedexecutionhandler handler = new myignorepolicy(); threadpoolexecutor executor = new threadpoolexecutor(corepoolsize, maximumpoolsize, keepalivetime, unit, workqueue, threadfactory, handler); executor.prestartallcorethreads(); // 预启动所有核心线程 for (int i = 1; i <= 10; i++) { mytask task = new mytask(string.valueof(i)); executor.execute(task); } system.in.read(); //阻塞主线程 } static class nametreadfactory implements threadfactory { private final atomicinteger mthreadnum = new atomicinteger(1); @override public thread newthread(runnable r) { thread t = new thread(r, "my-thread-" + mthreadnum.getandincrement()); system.out.println(t.getname() + " has been created"); return t; } } public static class myignorepolicy implements rejectedexecutionhandler { @override public void rejectedexecution(runnable r, threadpoolexecutor e) { dolog(r, e); } private void dolog(runnable r, threadpoolexecutor e) { // 可做日志记录等 system.err.println( r.tostring() + " rejected");// system.out.println("completedtaskcount: " + e.getcompletedtaskcount()); } } static class mytask implements runnable { private string name; public mytask(string name) { this.name = name; } @override public void run() { try { system.out.println(this.tostring() + " is running!"); thread.sleep(3000); //让任务执行慢点 } catch (interruptedexception e) { e.printstacktrace(); } } public string getname() { return name; } @override public string tostring() { return "mytask [name=" + name + "]"; } }}
运行结果:
其中7-10号线程被拒绝策略拒绝了,1、2号线程执行完后,3、6号线程进入核心线程池执行,此时4、5号线程在任务队列等待执行,3、6线程执行完再通知4、5线程执行
以上就是java自带的四种线程池是什么?的详细内容。
其它类似信息

推荐信息