2 adongsha adongsha 于 2018.10.11 19:57 提问

ThreadPoolExecutor添加线程不执行,为什么 5C

import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

public class MyBlockingQueue implements Runnable {

BlockingQueue<String> queue;

private int index;

public MyBlockingQueue(BlockingQueue<String> queue, int index) {
    this.queue = queue;
    this.index = index;
}

@Override
public void run() {
    try {
        queue.put(String.valueOf(this.index));
        System.out.println("{" + this.index + "} in queue!");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String args[]) {
    BlockingQueue<String> queue = new LinkedBlockingQueue<String>(3);

    ThreadFactory factory = new ThreadFactoryBuilder().setNameFormat("aaa-%s").build();
    ExecutorService pool = new ThreadPoolExecutor(5, 200, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024), factory, new ThreadPoolExecutor.AbortPolicy());

    for (int i = 0; i < 10; i++) {
        pool.submit(new MyBlockingQueue(queue, i));
    }

  //为什么这里的线程不执行呢?
    pool.submit(() -> {
        try {
            while (true) {
                System.out.println("=======" + queue.size());
                if (queue.isEmpty()) {
                    break;
                }
                String str = queue.take();
                System.out.println(str + " has take!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    });

    pool.shutdown();
}

}

1个回答

whandwho
whandwho   2018.10.11 21:18

首先想说一下,其中的问题,阻塞队列和工厂模式OK,
在创建线程池的时候并不建议使用ExecutorService 中的构造函数,而是使用Executors里面提供的四种静态方法,很多的参数配置已经写好。

其次,给线程池submit的应该是线程,而不是阻塞队列,你那里submit的是阻塞队列噢,循环体里面你可以写一个自己的类
比如(class MyThread extends Thread),再写一个print,sleep一下,就可以看到线程池的执行啦。

https://blog.csdn.net/whandwho/article/details/82931798 这个博客下方第八点

whandwho
whandwho 回复adongsha: 是我没有说清楚哇?最后的那一条,已经说清楚了嘛,有什么问题你再问嘛。
4 天之前 回复
whandwho
whandwho 回复adongsha: 我重新完整看了一遍你的代码。我帮你理一下你的思路,首先,你实现了runnable接口新建了一个线程类,线程类内部定义了index和一个string的阻塞队列。 其次,在main函数里面,你内部定义了一个String的阻塞队列,而针对线程池的阻塞队列,类型应该是线程类。 最后,你submit的是你自己定义的线程类,OK,然后你讲阻塞队列里面的取出来,取出来的是定义为String的阻塞队列内部内容。但是你实例化的是自己定义的实现runnable接口线程类MyBlockdeQuene.
4 天之前 回复
whandwho
whandwho 回复adongsha: 但是你submit的是队列,就算你这样是参考的阿里规范,按照你的意思,我submit的是阻塞队列,OK,没有问题。接着那么阻塞队列里面存放的应该是 Thread 线程,而不是 String。 所以就算你submit了一个队列,但是你队列里面存放的也不是线程Thread。
4 天之前 回复
whandwho
whandwho 接着那么阻塞队列里面存放的应该是 Thread 线程,而不是 String。
4 天之前 回复
whandwho
whandwho 回复adongsha: 但是你submit的是队列,就算你这样是参考的阿里规范,按照你的意思,我submit的是阻塞队列,OK,没有问题。
4 天之前 回复
adongsha
adongsha 这种方式的写法是参考阿里java规范的写法,你提倡的那种写法,阿里规范是不建议的哦
4 天之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐
java线程池之ThreadPoolExecutor(二):任务入队列和任务丢弃
除了前面描述涉及到的四个属性和ThreadFactory之外,还有两个分别是workQueue和handler,分别是BlockingQueue和RejectedExecutionHandler类型。 BlockingQueue只是一个接口,它所表达的是当队列为空或者已满的时候,需要阻塞以等待生产者/消费者协同操作并唤醒线程。其有很多不同的具体实现类,各有特点。有的可以规定队列的长度,也有一些则
使用ThreadPoolExecutor类创建线程池
一、采用这种方式的优点: 可以实时获取线程池内线程的各种状态 可以动态调整线程池大小 二、线程池的工作原理简介: 如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务; 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务
ThreadPoolExecutor在一个确定的队列下提交任务,如果执行队列满必须阻塞的解决方法
ThreadPoolExecutor在一个确定的队列下提交任务,如果执行队列满必须阻塞的解决方法
Java中的线程池——ThreadPoolExecutor的使用
开发过程中,合理地使用线程池可以带来3个好处: 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。 提高线程的可管理性:线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。 1 线程池的创建 ThreadPoolExecutor有
ThreadPoolExecutor是怎样执行任务的
先扯点别的:最近被公司外派到了嘉定区,新租了一个房子,马马虎虎,每天走路上班大约30分钟。早上8点半上班,下午5点半下班,和以前的作息规律有点不一样,逐渐适应,调整,然后还得把跑步这项运动坚持下来。 这篇文章(一天写不完)探索一下Java中的ThreadPoolExecutor的使用,感觉还是挺重要的。如果出去面试能把这个讲清楚,估计能唬住不少面试官,哈哈。 先给出一个简单的使用示例,然后再探...
ThreadPoolExecutor,worker和线程工厂之间理解
ThreadPoolExecutor中一个线程就是一个Worker对象,它与一个线程绑定,当Worker执行完毕就是线程执行完毕,这个在后面详细讨论线程池中线程的运行方式。而Worker带了锁,根据我后面准备写的读写锁的例子,发现线程池是线程安全的。看看图二的类图。
线程池的使用(ThreadPoolExecutor详解)
为什么要使用线程池? 线程是一个操作系统概念。操作系统负责这个线程的创建、挂起、运行、阻塞和终结操作。而操作系统创建线程、切换线程状态、终结线程都要进行CPU调度——这是一个耗费时间和系统资源的事情。  另一方面,大多数实际场景中是这样的:处理某一次请求的时间是非常短暂的,但是请求数量是巨大的。这种技术背景下,如果我们为每一个请求都单独创建一个线程,那么物理机的所有资源基本上都被操
Java线程池(ThreadPoolExecutor)原理分析与使用
在我们的开发中“池”的概念并不罕见,有数据库连接池、线程池、对象池、常量池等等。下面我们主要针对线程池来一步一步揭开线程池的面纱。使用线程池的好处1、降低资源消耗 可以重复利用已创建的线程降低线程创建和销毁造成的消耗。 2、提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行。 3、提高线程的可管理性 线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性
Java多线程之~~~使用ThreadPoolExecutor来创建线程
以前我们创建线程的时候都是主动的new一个Thread,然后调用他们的start方法,但是如果线程非常多,任务也非 常多的时候,这样写就会显得非常麻烦,当然可能效率也不是很高,Java给我们提供了叫线程创建器这个样概念的类, 他可以帮助我们管理这些线程,你做的就是编写好代码,然后交给他,她就会自动帮你运行。 当然,带cache的threadpool 对于死掉的线程重新调用,在性能上也会有非常
ThreadPoolExecutor 如何判断空闲线程
Worker public void run() {            runWorker(this); }        while (task != null || (task = getTask()) != null) { Runnable r = timed ?                    workQueue.poll(keepAliveTime, TimeUnit.NANO...