摘要:本篇来看下线程池相关技术的实现和使用方式。时间单位这个线程池中线程处理任务的的任务队列。上面的例子中我们向线程池中提交了一个,并接受一个返回值。
本篇来看下java线程池相关技术的实现和使用方式。
0x01 线程的实现一开始我们想要实现多线程最通常的做法是:
new Thread(new Runnable() { public void run() { System.out.println("raw thread"); } }).start();
这种方式,这种实现方式也没有什么不好,只是如果线程一多的话不好对所有的线程进行统一管理。然后java有了线程池技术,我们可以通过线程池技术来替换实现上面的方式。
0x02 线程池ExecutorService executorPool = Executors.newCachedThreadPool(); Futurefuture = executorPool.submit(new Callable () { public String call() throws Exception { return "future finish"; } }); try { System.out.println(future.get()); } catch (Exception e) { e.printStackTrace(); }
Executors有如下几种方式创建线程:
newCachedThreadPool
newFixedThreadPool
newScheduledThreadPool
上面三种方式最终都是调用ThreadPoolExecutor的构造函数进行线程池的创建,只是传入的参数不一样,而实现不同的线程池对象。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
corePoolSize:创建线程池时创建多少个线程。
maximumPoolSize:这个线程池中对多能有多少个线程。
keepAliveTime:当线程数量超过corePoolSize时,多余的空闲线程最大的存活时间。也就是说多余的线程在keepAliveTime时间还是没有处理任何的任务将会被终止。
unit:时间单位
workQueue:这个线程池中线程处理任务的的任务队列。
threadFactory:创建新线程的线程工厂。
handler:当线程数量达到maximumPoolSize,对新加入的任务的处理策略。一般很少使用这个参数基本都采用默认的handler。
上面的例子中我们向线程池中提交了一个Callable,并接受一个返回值Future。Callable可能会是一个非常耗时的操作但是使用方有不想阻塞等待其返回再继续执行,这时Callable执行完后会将结果放到Future中,使用方可以在需要的时候去判断是否Callable已经执行完成,如果完成就可以通过Future拿到其返回值。
0x03 ScheduledExecutorService任务定时调度线程的使用:
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleAtFixedRate(new Runnable() { public void run() { System.out.println("schedule task with fixed rate:" + System.currentTimeMillis()); } }, 2000, 1000, TimeUnit.MILLISECONDS); scheduledExecutorService.scheduleWithFixedDelay(new Runnable() { public void run() { System.out.println("schedule task with fixed delay:" + System.currentTimeMillis()); int count = Integer.MAX_VALUE; while (count-- > 0){ } System.out.println("time:" + System.currentTimeMillis()); } }, 2000, 1000, TimeUnit.MILLISECONDS);
ScheduledExecutorService有两种定时调度的方式:
scheduleAtFixedRate:以固定速率进行调度,意思是任何两个被调度的任务之间的时间间隔是固定的。第二个任务的调度时间(开始执行时间)= 第一个任务的调度时间 + 间隔时间
scheduleWithFixedDelay:第二个任务的调度时间 = 第一个任务的调度时间 + 第一个任务的执行时间 + 间隔时间
0x04 Timer定时任务上面介绍了ScheduledExecutorService来做定时任务,在编程的过程中还可以使用Timer来做定时任务,代码如下:
timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { try { doSomething(); } catch (Exception e) { System.out.println("timer excute exception", e); } } }, 1000 * 3, 1000);
其第一参数是一个TimerTask,第二第三个参数scheduledExecutorService.scheduleAtFixedRate这个调用的第二三个参数一致。
0x05 参考我觉得最好的参考还是阅读相关源码去理解Executor的使用方式,这样自己才能理解的比较深入同时做到活学活用。
线程池的的核心实现ThreadPoolExecutor,想了解更多还是自己去look look源码吧。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/66217.html
摘要:当活动线程核心线程非核心线程达到这个数值后,后续任务将会根据来进行拒绝策略处理。线程池工作原则当线程池中线程数量小于则创建线程,并处理请求。当线程池中的数量等于最大线程数时默默丢弃不能执行的新加任务,不报任何异常。 spring-cache使用记录 spring-cache的使用记录,坑点记录以及采用的解决方案 深入分析 java 线程池的实现原理 在这篇文章中,作者有条不紊的将 ja...
摘要:四种线程池的使用介绍的弊端及四种线程池的使用,线程池的作用线程池作用就是限制系统中执行线程的数量。相比,提供的四种线程池的好处在于重用存在的线程,减少对象创建消亡的开销,性能佳。延迟执行描述创建一个定长线程池,支持定时及周期性任务执行。 java 四种线程池的使用 介绍new Thread的弊端及Java四种线程池的使用 1,线程池的作用 线程池作用就是限制系统中执行线程的数量。 ...
摘要:高并发系列第篇文章。简单的说,在使用了线程池之后,创建线程变成了从线程池中获取一个空闲的线程,然后使用,关闭线程变成了将线程归还到线程池。如果调用了线程池的方法,线程池会提前把核心线程都创造好,并启动线程池允许创建的最大线程数。 java高并发系列第18篇文章。 本文主要内容 什么是线程池 线程池实现原理 线程池中常见的各种队列 自定义线程创建的工厂 常见的饱和策略 自定义饱和策略 ...
阅读 1320·2021-11-24 09:38
阅读 3257·2021-11-22 12:03
阅读 4165·2021-11-11 10:59
阅读 2320·2021-09-28 09:36
阅读 1034·2021-09-09 09:32
阅读 3414·2021-08-05 10:00
阅读 2531·2021-07-23 15:30
阅读 2975·2019-08-30 13:12