• threadpoolExecutor----自动执行任务


    使用threadpoolExecutor,主要是任务的提交的执行和获取结果。

    提交任务的方法有:

    1、submit
    2、execute
    3、queue的add

    其中1和2的使用必须是threadpoolExecutor的实例,直接提交。两种做法:1、暴露threadpool实例,2、封装threadpool,然后提供一个代理或decorator类似的东西进行任务提交。

    联系到threadpoolexecutor内部使用的queue是blockingqueue:阻塞读取和插入,可以利用该queue作为管道,输送任务对象,而threadpool实例直接等待队列的数据。

    BUT,问题在于threadpoolExecutor在实例化之后(new),池子是空的,并不会自动将线程数(taskRunner的数)初始化,怎么使其初始化呢(有了线程后,线程在timeout时间内等待任务,若需要其不用timeout呢,直接为0即可):可以在初始化之后先添加一个或多个空任务:

     1 queue = new CrawTaskBlockingQueue(capacity);
     2         executors = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, queue);
     3         //模拟开始
          for (int i = 0; i < corePoolSize; i++) 4   executors.submit(new Callable<T>() { 5 6   public T call() { 7   LogUtil.debug(logger, "executors test start..........."); 8    return null; 9    } 10   });

    任务启动后,只需要向queue提交任务即可:

    1 queue.offer(task);

     当然,这样做的问题比较大:

    1、直接往threadpool提交任务时,如果threadpool 没有到达最大线程数,会直接创建线程执行任务,而不会进去queue;这种方式的统一入口却是queue:统一入queue,而且maxpoolSize>corepoolSize时,thread不会增加,是个弊端。

    2、Threadpool有RejectedExecution的机制,在无法往queue中offer的时候,会调用一个拒绝机制。而直接调用add方法,一般的queue实现中,会尝试一下offer,没有拒绝以后的机制。但是如果没有特殊reject的指定,这一条不使用也没什么。直接queue的插入阻塞即可满足。

  • 相关阅读:
    基于ADO的远程Oracle连接
    oracle中的定时任务
    关于C++ const 变量
    堆排序和选择排序
    插入排序
    多线程的两种启动方式
    多尺度变换去噪的阈值选择
    jstree
    JS中call、apply、bind使用指南,带部分原理。
    六. JavaScript时间日期格式化
  • 原文地址:https://www.cnblogs.com/leeying/p/3778114.html
Copyright © 2020-2023  润新知