java线程池

发布时间:2019-11-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了java线程池脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

本篇来看下java线程池相关技的实现和使用方式。

0x01 线程的实现

开始我们想要实现多线程最通常的做法是:

new Thread(new Runnable() {     public void run() {         System.out.PRintln("raw thread");     } }).start();

这种方式,这种实现方式也没有什么不好,只是如果线程一多的话不好对所有的线程进行统一管理。然后java有了线程池技术,我们可以通过线程池技术来替换实现上面的方式。

0x02 线程池

ExecutorService executorPool = Executors.newCachedThreadPool(); Future<String> future = executorPool.submit(new Callable<String>() {     public String call() throws Exception {         return "future finish";     } }); try {     System.out.println(future.get()); } catch (Exception e) {     e.printStackTrace(); }

Executors有如下几种方式创建线程:

  1. newCachedThreadPool

  2. newFixedThreadPool

  3. newScheduledThreadPool

上面三种方式最终都是调用ThreadPoolExecutor的构造函数进行线程池的创建,只是传入的参数不一样,而实现不同的线程池对象。

ThreadPoolExecutor(int corePoolSize,                       int maximumPoolSize,                       long keepAliveTime,                       TimeUnit unit,                       BlockingQueue<Runnable> workQueue,                       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有两种定时调度的方式:

  1. scheduleAtFixedRate:以固定速率进行调度,意思是任何两个被调度的任务之间的时间间隔是固定的。第二个任务的调度时间(开始执行时间)= 第一个任务的调度时间 + 间隔时间

  2. 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源码吧。

脚本宝典总结

以上是脚本宝典为你收集整理的java线程池全部内容,希望文章能够帮你解决java线程池所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。