资讯专栏INFORMATION COLUMN

java线程池

233jl / 1034人阅读

摘要:本篇来看下线程池相关技术的实现和使用方式。时间单位这个线程池中线程处理任务的的任务队列。上面的例子中我们向线程池中提交了一个,并接受一个返回值。

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

0x01 线程的实现

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

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

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

0x02 线程池
ExecutorService executorPool = Executors.newCachedThreadPool();
Future future = 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,
                      BlockingQueue 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有两种定时调度的方式:

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

相关文章

  • Java线程

    摘要:中的线程池是运用场景最多的并发框架。才是真正的线程池。存放任务的队列存放需要被线程池执行的线程队列。所以线程池的所有任务完成后,它最终会收缩到的大小。饱和策略一般情况下,线程池采用的是,表示无法处理新任务时抛出异常。 Java线程池 1. 简介 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互,这个时候使用线程池可以提升性能,尤其是需要创建大量声明周期很短暂的线程时。Ja...

    jerry 评论0 收藏0
  • 后端ing

    摘要:当活动线程核心线程非核心线程达到这个数值后,后续任务将会根据来进行拒绝策略处理。线程池工作原则当线程池中线程数量小于则创建线程,并处理请求。当线程池中的数量等于最大线程数时默默丢弃不能执行的新加任务,不报任何异常。 spring-cache使用记录 spring-cache的使用记录,坑点记录以及采用的解决方案 深入分析 java 线程池的实现原理 在这篇文章中,作者有条不紊的将 ja...

    roadtogeek 评论0 收藏0
  • java 四种线程的使用

    摘要:四种线程池的使用介绍的弊端及四种线程池的使用,线程池的作用线程池作用就是限制系统中执行线程的数量。相比,提供的四种线程池的好处在于重用存在的线程,减少对象创建消亡的开销,性能佳。延迟执行描述创建一个定长线程池,支持定时及周期性任务执行。 java 四种线程池的使用 介绍new Thread的弊端及Java四种线程池的使用 1,线程池的作用 线程池作用就是限制系统中执行线程的数量。 ...

    gggggggbong 评论0 收藏0
  • Java 线程

    系统启动一个线程的成本是比较高,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短暂的线程时 线程池在系统启动时即创建大量空闲线程,将一个Runnable、Callable对象—–>传给线程池—–>线程池启动里面的一个线程来执行它们的run()或者call()方法———->当线程执行体执行完成后,线程并不会死亡,而是再次返回线程池成为空闲状态,等待下一个Runnable、Calla...

    ctriptech 评论0 收藏0
  • 跟着阿里p7一起学java高并发 - 第18天:玩转java线程,这一篇就够了

    摘要:高并发系列第篇文章。简单的说,在使用了线程池之后,创建线程变成了从线程池中获取一个空闲的线程,然后使用,关闭线程变成了将线程归还到线程池。如果调用了线程池的方法,线程池会提前把核心线程都创造好,并启动线程池允许创建的最大线程数。 java高并发系列第18篇文章。 本文主要内容 什么是线程池 线程池实现原理 线程池中常见的各种队列 自定义线程创建的工厂 常见的饱和策略 自定义饱和策略 ...

    AdolphLWQ 评论0 收藏0
  • Java中的线程

    摘要:中的线程池运用场景非常广泛,几乎所有的一步或者并发执行程序都可以使用。代码中如果执行了方法,线程池会提前创建并启动所有核心线程。线程池最大数量线程池允许创建的线程最大数量。被称为是可重用固定线程数的线程池。 Java中的线程池运用场景非常广泛,几乎所有的一步或者并发执行程序都可以使用。那么线程池有什么好处呢,以及他的实现原理是怎么样的呢? 使用线程池的好处 在开发过程中,合理的使用线程...

    tomato 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<