ForkJoinPool parallelism = 1 deadlock [英] ForkJoinPool parallelism=1 deadlock

查看:255
本文介绍了ForkJoinPool parallelism = 1 deadlock的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用jsr166y ForkJoinPool在线程之间分配计算任务。

I'm using the jsr166y ForkJoinPool to distribute computational tasks amongst threads. But I clearly must be doing something wrong.

如果我创建ForkJoinPool并行性> 1(默认是Runtime.availableProcessors();我的任务似乎工作完美无瑕已经用2-8线程运行)。但是如果我用parallelism = 1创建ForkJoinPool,我在不可预测的迭代次数后看到死锁。

My tasks seem to work flawlessly if I create the ForkJoinPool with parallelism > 1 (the default is Runtime.availableProcessors(); I've been running with 2-8 threads). But if I create the ForkJoinPool with parallelism = 1, I see deadlocks after an unpredictable number of iterations.

是的 - 设置parallelism = 1是一个奇怪的做法。在这种情况下,我正在分析并行算法,因为线程计数增加,我想比较并行版本,单线程运行到基线串行实现,以便准确确定并行实现的开销。

Yes - setting parallelism = 1 is a strange practice. In this case, I'm profiling a parallel algorithm as thread-count increases, and I want to compare the parallel version, run with to a single thread, to a baseline serial implementation, so as to accurately ascertain the overhead of the parallel implementation.

下面是一个简单的例子,说明我看到的问题。 任务是固定数组上的虚拟迭代,递归地分成16个子任务。

Below is a simple example that illustrates the issue I'm seeing. The 'task' is a dummy iteration over a fixed array, divided recursively into 16 subtasks.

如果使用THREADS = 2(或更多)运行,它将可靠地运行到完成,但如果使用THREADS = 1运行,则它总是死锁。在不可预测的迭代次数之后,主循环在ForkJoinPool.invoke()中挂起,等待task.join(),并且工作线程退出。

If run with THREADS = 2 (or more), it runs reliably to completion, but if run with THREADS = 1, it invariably deadlocks. After an unpredictable number of iterations, the main loop hangs in ForkJoinPool.invoke(), waiting on task.join(), and the worker thread exits.

在Linux下使用JDK 1.6.0_21和1.6.0_22运行,并且使用几天前从Doug Lea网站下载的jsr166y版本( http://gee.cs.oswego.edu/dl/concurrency-interest/index.html

I'm running with JDK 1.6.0_21 and 1.6.0_22 under Linux, and using a version of jsr166y downloaded a few days ago from Doug Lea's website (http://gee.cs.oswego.edu/dl/concurrency-interest/index.html)

任何建议为什么我错过了?非常感谢。

Any suggestions for what I'm missing? Many thanks in advance.

package concurrent;

import jsr166y.ForkJoinPool;
import jsr166y.RecursiveAction;

public class TestFjDeadlock {

    private final static int[] intArray = new int[256 * 1024];
    private final static float[] floatArray = new float[256 * 1024];

    private final static int THREADS = 1;
    private final static int TASKS = 16;
    private final static int ITERATIONS = 10000;

    public static void main(String[] args) {

        // Initialize the array
        for (int i = 0; i < intArray.length; i++) {
            intArray[i] = i;
        }

        ForkJoinPool pool = new ForkJoinPool(THREADS);

        // Run through ITERATIONS loops, subdividing the iteration into TASKS F-J subtasks
        for (int i = 0; i < ITERATIONS; i++) {
            pool.invoke(new RecursiveIterate(0, intArray.length));
        }

        pool.shutdown();
    }

    private static class RecursiveIterate extends RecursiveAction {

        final int start;
        final int end;

        public RecursiveIterate(final int start, final int end) {
            this.start = start;
            this.end = end;
        }

        @Override
        protected void compute() {

            if ((end - start) <= (intArray.length / TASKS)) {
                // We've reached the subdivision limit - iterate over the arrays
                for (int i = start; i < end; i += 3) {
                    floatArray[i] += i + intArray[i];
                }

            } else {
                // Subdivide and start new tasks
                final int mid = (start + end) >>> 1;
                invokeAll(new RecursiveIterate(start, mid), new RecursiveIterate(mid, end));
            }
        }
    }
}


推荐答案

看起来像是一个在ForkJoinPool中的错误。一切我可以看到在类的用法适合你的例子。唯一的其他可能性可能是你的一个任务抛出异常和异常死亡(虽然这仍应该处理)。

looks like a bug in the ForkJoinPool. everything i can see in the usage for the class fits your example. the only other possibility might be one of your tasks throwing an exception and dying abnormally (although that should still be handled).

这篇关于ForkJoinPool parallelism = 1 deadlock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆