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方法运行时等待另一个线程。这种情况使我的应用程序速度降低了三倍。
使用语言环境时是否缺少某些东西,或者出于相同的目的必须使用其他类?
提前致谢。
编辑:该解决方案波纹管实际上不会工作,因为有问题HashTable
的java.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)
经过短暂的探索,JDK似乎无法为您提供帮助。我建议获取java.lang.ConditionalSpecialCasing
类,将其复制并解决Hashtable的问题。您可以替换Hashtable
为HashMap
。我看不到Hashtable
在这里使用任何理由。
upperCaseEN
用途 Local.ENGLISH
upperCaseTR
用途 new Locale("tr", "TR")
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)
使用修补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