多线程 - Java中在子线程中获取固定大小的连接池出现错误,如果解释?
黄舟
黄舟 2017-04-18 09:55:58
0
2
500

问题1. 不太好描述,直接看代码吧

public class QueueConsumer extends EndPoint implements Runnable {

    // 线程池
    private ExecutorService executor = null;

    public QueueConsumer(String endPointName, String hosts, String ports,
            String username, String password) throws Exception {
        super(endPointName, hosts, ports, username, password);
        // 初始化线程池
        executor = Executors.newCachedThreadPool();
    }

    @Override
    public void run() {
        try {
            QueueingConsumer consumer = new QueueingConsumer(channel);
            channel.basicConsume(endPointName, false, consumer);
            while (true) {

                // 信息到达时
                Delivery delivery = consumer.nextDelivery();
                
                // 初始化业务线程对象
                BusinessClient businessClient = new BusinessClient(channel, delivery);
                // 执行任务
                executor.execute(businessClient);
            }
        } catch (Exception e) {
            LogUtil.printException("消息队列异常", e, LogUtil.LOG_LEVEL_ERROR);
        } finally {
            try {
                close();
            } catch (Exception e) {
                LogUtil.printException("关闭消息队列异常", e, LogUtil.LOG_LEVEL_ERROR);
            }
        }
    }
}

public class BusinessClient implements Runnable {
    ... 省略
    
    // 主要代码
    List<Callable<Object>> taskList = new ArrayList<Callable<Object>>();
    for (BaseRequestData<BaseResponseData> queryData : queryDataLst) {
        QueryThread queryThread = new QueryThread(queryData);
        taskList.add(queryThread);
    }

    // 问题点:此处使用Executors.newFixedThreadPool(i)会抛出IllegalArgumentException
              但是使用Executors.newCachedThreadPool()则不会有问题.不是很理解,为什么此处不可以用newFixedThreadPool(i)?
              
    ExecutorService executor = Executors.newCachedThreadPool();
    List<Future<Object>> results = executor.invokeAll(taskList);
    executor.shutdown();
    
    ... 省略
}

问题2. 我如果定义一个线程池工厂,将线程池定义为static final,每个需要并发的地方都使用工厂来获得线程池,

   那么问题来了,我这个线程池会自动扩展或者释放线程吗?
   
   

纯粹自学的Java, 对于一些基础知识不是很理解,望不吝赐教!谢谢

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

reply all(2)
刘奇

1. Executors.newFixedThreadPool(nThreads ):IllegalArgumentException - if nThreads <= 0
2、final means that your thread pool address will not change, but there is no limit on the threads in the thread pool.

PHPzhong

Executors.newFixedThreadPool(i) 此处的i取值范围不对吧,如果你出现IllegalArgumentException,说明这个值是小于0 That’s not allowed.

Executors.newFixedThreadPool(i) The following logic will eventually follow.

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!