如何在多线程应用程序中使用语言环境以提高性能

Erd*_*gil 8 java multithreading

在我的应用程序中,我有一个同时被多个线程调用的方法。每个线程在运行时都会多次调用此方法。

private Locale trLoc = new Locale("tr", "TR");

public double calculate(String arg1){
    arg1 = arg1.toUpperCase(trLoc);
...
}
Run Code Online (Sandbox Code Playgroud)

此方法进行String.toUpperString(Locale)调用,由于Locale类中的HashTable用法而导致瓶颈。每个线程在toUpperCase方法运行时等待另一个线程。这种情况使我的应用程序速度降低了三倍。

使用语言环境时是否缺少某些东西,或者出于相同的目的必须使用其他类?

提前致谢。

Cyä*_*gha 5

编辑:该解决方案波纹管实际上不会工作,因为有问题HashTablejava.lang.ConditionalSpecialCasing类是静态的,仍然会被所有线程共享。我建议你接受 sibnick 的回答而不是我的。


一个简单的解决方案是使 trLoc a ThreadLocal:将为每个线程自动创建一个新实例(根据需要)。如果您有线程池或类似的东西,这将工作正常:您将只创建与池中的线程一样多的实例Locale,这应该是非常合理的。并且由于每个线程将访问 的不同实例Locale,您将不再有访问同步 HashTable 的争用。

private ThreadLocal<Locale> trLoc = new ThreadLocal<Locale>() {
    @Override
    protected Locale initialValue() {
        return new Locale("tr", "TR");
    }
};

public double calculate(String arg1){
    arg1 = arg1.toUpperCase(trLoc.get());
    ...
}
Run Code Online (Sandbox Code Playgroud)


sib*_*ick 5

经过短暂的探索,JDK似乎无法为您提供帮助。我建议获取java.lang.ConditionalSpecialCasing类,将其复制并解决Hashtable的问题。您可以替换HashtableHashMap。我看不到Hashtable在这里使用任何理由。

  • 可能值得向Oracle报告此问题(http://bugreport.java.com)-我愿意这样做,但是我认为,最好由实际遇到此问题的人提出RFE,可以提供一个测试用例。 (2认同)

Sub*_*mal 5

根据@sibnick的回答,我运行了一些JMH基准测试。

  • upperCaseEN 用途 Local.ENGLISH
  • upperCaseTR 用途 new Locale("tr", "TR")

JDK 8

Benchmark                              Mode  Samples     Score  Score error   Units
s.o.MyBenchmark.upperCaseEN           thrpt       25  9680.129       89.485  ops/ms
s.o.MyBenchmark.upperCaseTR           thrpt       25   992.973        6.306  ops/ms
Run Code Online (Sandbox Code Playgroud)

JDK 8 已修补

使用修补ConditionalSpecialCasing类 usingHashMap而不是Hashtable

Benchmark                              Mode  Samples     Score  Score error   Units
s.o.MyBenchmark.upperCaseTR           thrpt       25  3331.277       77.691  ops/ms
Run Code Online (Sandbox Code Playgroud)

另一种解决方案可能是首先扫描包含小写的字符串i。因为这似乎是唯一需要toUpperCase在土耳其语语言环境中进行特殊处理的字符。

if (state.lowercase.contains("i")) {
    uppercase = lowercase.toUpperCase(TR_LOCALE));
} else {
    uppercase = lowercase.toUpperCase(EN_LOCALE));
}
Run Code Online (Sandbox Code Playgroud)

这已经提高了性能。

Benchmark                              Mode  Samples     Score  Score error   Units
s.o.MyBenchmark.upperCasePatchedTR    thrpt       25  8753.116       51.582  ops/ms
Run Code Online (Sandbox Code Playgroud)

编辑基准代码可以在

https://github.com/SubOptimal/stackoverflow-answers/tree/master/question-31987777