为什么我的fork / join死锁?

时间:2011-09-27 04:00:40

标签: java groovy parallel-processing fork-join

考虑以下剪切代码,它计算给定的所有路径的大小。

def pathSizes = []
paths.each { rootPath ->
  pathSizes.addAll(
    withPool { pool ->
      runForkJoin(rootPath) { path ->
        def headSizes = [:]
        println path

        def lines = ["ls", "-al", path].execute().text.readLines()
        (0..<3).each { lines.remove(0) }
        lines.each { line ->
          def fields = line.split(/\s+/)
          if (fields[0] =~ /^d/)
            forkOffChild("$path/${fields.last()}")
          else {
            def userName = fields[2]
            def fileSize = fields[4] as long
            if (headSizes[userName] == null)
              headSizes[userName] = fileSize
            else
              headSizes[userName] += fileSize
          }
        }

        quietlyJoin()
        System.gc()

        def shallowSizes =
          headSizes.collectEntries { userName, fileSize ->
            def childResult =
              childrenResults.sum {
                 it.shallowSizes[userName] ? it.shallowSizes[userName] : 0
              } ?: 0
            return [userName, fileSize + childResult]
          }

        def deepSizes =
          childrenResults.sum { it.deepSizes ?: [] } +
          shallowSizes.collect { userName, fileSize ->
            [userName: userName, path: path, fileSize: fileSize]
          }

        return [shallowSizes: shallowSizes, deepSizes: deepSizes]
      }.deepSizes
    })
}

为什么这段代码会死锁?除了可能与系统调用和Java框架的其他部分之外,线程之间没有交互。如果系统调用是问题,那么如何修复它,而不删除系统调用(它们很慢,因此需要并行化)?

0 个答案:

没有答案