有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

共享同一阻塞队列的java ThreadPoolExecutor

我有一个场景,两个线程池实例共享同一个阻塞队列。这是密码

<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到TaskThreadPool2中提交5个以上的任务,行为会是什么。执行(任务)

我觉得TaskThreadPool1也应该开始执行这些任务,因为它也在侦听相同的队列


共 (2) 个答案

  1. # 1 楼答案

    不,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()激活

  2. # 2 楼答案

    真的想不出为什么在同一个阻塞队列中有两个线程池。最好的方法是制作一个程序并运行它

    既然说不需要两个这样的游泳池,那就把游泳池的规模扩大一倍

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