Java 工具类 —— Java线程池使用的五种方式

线程池的使用可以实现线程的重用,大大节省了系统资源,优化了系统性能。前面讲过线程池的实现原理和源代码分析。基础篇--------浅谈JAVA线程池(源码解析)有兴趣的小伙伴欢迎查看。本章就记录一下线程池使用的五种方式,也可以说是6种。

下方内容所有源码:https://download.csdn.net/download/u011909918/11505361

小板凳搬过来坐好。


先上周边代码,自定义线程,自定义线程池中超出队列大小之后提交任务处理机制(等一段时间提交)

/**
     * 线程工厂,用于提交任务给线程池
     */
    static class MyTherd implements Runnable {

        private String message;

        public MyTherd(String message) {
            this.message = message;
        }

        @Override
        public void run() {
            //此处实现业务逻辑
        }
    }

    /**
     * 线程池队列中任务超出最大数量处理机制
     */
    static class MyHandler implements RejectedExecutionHandler{
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            try {
                logger.info("MQLitener: current threads count is: " + executor.getActiveCount());
                Thread.sleep(3000); //等待3S,消息队列有空闲,重新提交
                executor.execute(r);
            }catch (Exception e){
                logger.error("MQLitener: RejectedExecutionHandler Error", e);
            }
        }
    }

    /**
     * 代码入口
     */
    public static void main(String[] args) {
        String message = "";
        executor.execute(new MyTherd(message));
    }

创建线程池(Create Thread pool):

----------------------------------------废话不多说,直接上代码--------------------------------------------------

Method one(原始创线程池):

private static Integer corePoolSize = 70; //最大核心线程数
    private static Integer maximumPoolSize = 100; //最大线程数
    private static Integer keepAliveTime = 10; //线程允许空闲时间
    private static Integer maxQueueSize = 500; //阻塞队列最大数量
    //线程池
    private static ExecutorService executor = new ThreadPoolExecutor(corePoolSize, //核心线程数
            maximumPoolSize, //最大线程数
            keepAliveTime,
            TimeUnit.SECONDS, //线程允许空闲时间单位
            new ArrayBlockingQueue<>(maxQueueSize, true), //线程池阻塞队列, 也可以用LinkedBlockingQueue等其他队列
            new MyHandler());

corePoolSize ------------消息队列不超过maxQueueSize 时可以创建的最大线程数;

maximumPoolSize --------------消息队列超过maxQueueSize时会创建新的线程知道达到最大线程数;

maxQueueSize -----------消息队列中可以保存的最大消息数量

keepAliveTime -----------无任务执行时线程存活时间

 

注意:下面的方式不建议在线上使用,因为它们的消息队列都是无界的。

 

Method two(缓存线程池):

//创建缓存线程池-----不限制线程数量,只要机器资源足够,进来一个任务,创建一个线程(看下面源码)
private static ExecutorService executor = Executors.newCachedThreadPool();

这个源码是这样的,根据Method one 自行理解:

/**
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to {@code execute} will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     */
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

Method three(定长线程池):

//创建定长线程池 线程池的最大核心线程数和最大线程数相等且固定,为入参
private static ExecutorService executor = Executors.newFixedThreadPool(corePoolSize);

这个源码是这样的,根据Method one 自行理解:

/**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * {@code nThreads} threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if {@code nThreads <= 0}
     */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

Method four(单例线程池):

//创建单例线程池 线程池中只有一个线程只执行任务,其他任务都在排队
private static ExecutorService executor = Executors.newSingleThreadExecutor();

这个源码是这样的,根据Method one 自行理解:

/**
     * Creates an Executor that uses a single worker thread operating
     * off an unbounded queue. (Note however that if this single
     * thread terminates due to a failure during execution prior to
     * shutdown, a new one will take its place if needed to execute
     * subsequent tasks.)  Tasks are guaranteed to execute
     * sequentially, and no more than one task will be active at any
     * given time. Unlike the otherwise equivalent
     * {@code newFixedThreadPool(1)} the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     *
     * @return the newly created single-threaded Executor
     */
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

Method five(任务线程池):

//创建定长可执行任务线程池
    private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(corePoolSize);

    //创建单例可执行任务线程池
    private static ScheduledExecutorService singleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

    public static void main(String[] args) {
        String message = "";

        //定时任务线程池的使用,singleThreadScheduledExecutor同理
        scheduledThreadPool.execute(new MyTherd(message)); //普通使用
        scheduledThreadPool.schedule(new MyTherd(message), 2, TimeUnit.SECONDS); //延迟两秒执行
        scheduledThreadPool.scheduleAtFixedRate(new MyTherd(message), 2, 4, TimeUnit.SECONDS); //延迟两秒每4秒执行一次
    }

这个源码是这样的:

/*******************创建,返回结果ScheduledExecutorService **********************/

/**
     * Creates a thread pool that can schedule commands to run after a
     * given delay, or to execute periodically.
     * @param corePoolSize the number of threads to keep in the pool,
     * even if they are idle
     * @return a newly created scheduled thread pool
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     */
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

/**
     * Creates a single-threaded executor that can schedule commands
     * to run after a given delay, or to execute periodically.
     * (Note however that if this single
     * thread terminates due to a failure during execution prior to
     * shutdown, a new one will take its place if needed to execute
     * subsequent tasks.)  Tasks are guaranteed to execute
     * sequentially, and no more than one task will be active at any
     * given time. Unlike the otherwise equivalent
     * {@code newScheduledThreadPool(1)} the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     * @return the newly created scheduled executor
     */
    public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
        return new DelegatedScheduledExecutorService
            (new ScheduledThreadPoolExecutor(1));
    }



/*******************************使用********************************************/
/**
     * Creates and executes a periodic action that becomes enabled first
     * after the given initial delay, and subsequently with the given
     * period; that is executions will commence after
     * {@code initialDelay} then {@code initialDelay+period}, then
     * {@code initialDelay + 2 * period}, and so on.
     * If any execution of the task
     * encounters an exception, subsequent executions are suppressed.
     * Otherwise, the task will only terminate via cancellation or
     * termination of the executor.  If any execution of this task
     * takes longer than its period, then subsequent executions
     * may start late, but will not concurrently execute.
     *
     * @param command the task to execute
     * @param initialDelay the time to delay first execution
     * @param period the period between successive executions
     * @param unit the time unit of the initialDelay and period parameters
     * @return a ScheduledFuture representing pending completion of
     *         the task, and whose {@code get()} method will throw an
     *         exception upon cancellation
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if command is null
     * @throws IllegalArgumentException if period less than or equal to zero
     */
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);

/**
     * Creates and executes a one-shot action that becomes enabled
     * after the given delay.
     *
     * @param command the task to execute
     * @param delay the time from now to delay execution
     * @param unit the time unit of the delay parameter
     * @return a ScheduledFuture representing pending completion of
     *         the task and whose {@code get()} method will return
     *         {@code null} upon completion
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if command is null
     */
    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);

OK,上面就是线程池的花式使用方式,与君共勉~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值