java中的线程没有并发运行

时间:2012-01-30 11:19:03

标签: java multithreading

我在Java中遇到多线程问题。我需要将一大串名称与自身进行比较(以找到近似重复的名称)。

我将工作分成4个不同的线程,每个线程将列表的1/4与完整列表进行比较。我为所有4个线程使用相同的类。

当我看到线程监视器时,我发现它们并没有真正同时运行,它们一个接一个地处于活动状态。

可能是什么问题?

这是我的线程类的运行方法:

@Override
    public void run() {
        try {
            s = settings.conn.createStatement();
            JaroWinklerDistance jw = JaroWinklerDistance.JARO_WINKLER_DISTANCE;

        for (int i = 0; i < names.size(); i++) {
            for (int j = 0; j < allNames.size(); j++) {
                if (j % 250 == 0) {
                }
                double proximity = jw.proximity(names.get(i), allNames.get(j));
                if (proximity > Double.parseDouble(settings.properties.getProperty("distanceTreshold")) && proximity < 1.00) {
                    if (names.get(i).length() > allNames.get(j).length()) {
                        substituteName(allNames.get(j), names.get(i));
                        allNames.remove(allNames.get(j));
                    } else {
                        substituteName(names.get(i), allNames.get(j));
                        names.remove(names.get(i));
                        break;
                    }
                }
            }
        }
    } catch (SQLException ex) {
        Exceptions.printStackTrace(ex);
    }
}

substituteName-method执行更新记录的SQL查询。

线程创建如下:

settings.getAllNames();
        int size = settings.allNames.size();
        int rest = size % 4;
        int groupSize = (size-rest) / 4;

        GroupNormalizer a = new GroupNormalizer(settings.allNames, new ArrayList<String>(settings.allNames.subList(0, groupSize)));
        GroupNormalizer b = new GroupNormalizer(settings.allNames, new ArrayList<String>(settings.allNames.subList(groupSize, (groupSize*2))));
        GroupNormalizer c = new GroupNormalizer(settings.allNames, new ArrayList<String>(settings.allNames.subList((groupSize * 2), (groupSize * 3))));
        GroupNormalizer d = new GroupNormalizer(settings.allNames, new ArrayList<String>(settings.allNames.subList((groupSize * 3), (groupSize*4 + rest))));
        a.start();
        b.start();
        c.start();
        d.start();

编辑:所有4个线程在运行和监控(阻止)-status之间交替运行

4 个答案:

答案 0 :(得分:3)

Executor Framework(线程池)来救援!

  

线程池管理工作线程池。线程池   包含一个工作队列,用于保存等待执行的任务。

答案 1 :(得分:2)

嗯,看起来这条线导致同步锁定:

if (proximity > Double.parseDouble(settings.properties.getProperty("distanceTreshold")) && proximity < 1.00)

尝试将Double.parseDouble拉出循环,因为那里的所有内容对我来说都是不变的。

似乎设置对象阻止了ob访问,这样会减慢你的速度。

在您的计算过程中看起来您正在访问数据库(捕获SQLEx),这会使您的速度降低很多。尝试将读取和写入与计算过程分开。

答案 2 :(得分:1)

试试ForkJoin

答案 3 :(得分:0)

在多个线程中同时使用Java中的Double.parseDouble存在一个已知问题。它在内部用于解析的方法是同步的,因此如果你有很多线程同时调用它,那么线程最终会被阻塞。

这应该在Java 8中修复。

(参见Java错误报告JI-9004591 - “从多个线程调用Double.parseDouble时监视争用” - http://bugs.sun.com/view_bug.do?bug_id=7032154

我怀疑这就是为什么在接受的答案(将Double.parseDouble移出)中所做的更改提高了性能。