ThreadPoolExecutor共享相同的阻塞队列

时间:2012-11-19 04:11:04

标签: java

我有一个场景,其中两个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(任务)在TaskThreadPool2中提交超过5个任务会有什么行为。

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

2 个答案:

答案 0 :(得分:0)

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

虽然说不需要有两个这样的池,但要将池的大小增加一倍。

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

答案 1 :(得分: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

执行程序已使用execute()激活。