0

我有一个场景,两个 threadPool 实例共享同一个阻塞队列。这是代码

<bean id="TaskQueue" class="java.util.concurrent.LinkedBlockingQueue">
        <constructor-arg type="int">
            <value>1000</value>
        </constructor-arg>
    </bean>

    <bean id="TaskThreadPool1" class="java.util.concurrent.ThreadPoolExecutor">
        <constructor-arg type="int">
            <value>10</value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>50</value>
        </constructor-arg>
        <constructor-arg type="long">
            <value>5</value>
        </constructor-arg>
        <constructor-arg>
            <value>SECONDS</value>
        </constructor-arg>
        <constructor-arg>
            <ref bean="TaskQueue" />
        </constructor-arg>
    </bean>


    <bean id="TaskThreadPool2" class="java.util.concurrent.ThreadPoolExecutor">
        <constructor-arg type="int">
            <value>1</value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>1</value>
        </constructor-arg>
        <constructor-arg type="long">
            <value>5</value>
        </constructor-arg>
        <constructor-arg>
            <value>SECONDS</value>
        </constructor-arg>
        <constructor-arg>
            <ref bean="TaskQueue" />
        </constructor-arg>
    </bean>

现在我有一个问题,如果我通过 TaskThreadPool2.execute(task) 在 TaskThreadPool2 中提交超过 5 个任务会怎样。

我觉得TaskThreadPool1 也应该开始执行这些任务,因为它也在监听同一个队列。

4

2 回答 2

0

不,TaskThreadPool1 不会执行队列中的任务,请参阅 ThreadPoolExecutor 构造函数(源代码) - 它不会开始监听工作队列。您可以轻松地对其进行测试:

    BlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
    Runnable r = new Runnable() {
        public void run() {
            System.out.println("running");
        }
    };
    q.add(r);
    q.add(r);
    ThreadPoolExecutor ex1 = new ThreadPoolExecutor(10, 50, 5, TimeUnit.SECONDS, q);

运行它,没有任何反应,ex1 忽略队列中的任务。但是添加这个

    ex1.execute(r);

你会看到

    running
    running
    running

Executor 是用 execute() 激活的。

于 2012-11-19T05:57:40.990 回答
0

真的想不出有两个线程池用于同一个阻塞队列的原因。最好的找出方法是制作一个程序并运行它。

话虽如此,不需要两个这样的池,将池的大小增加一倍。

此外,如果您想拥有两个池,请检查并发性,因为可能存在两个池中的一个线程会尝试访问队列中的相同资源的情况。这可能会导致不可预知的结果。

于 2012-11-19T05:28:48.230 回答