travis-ciの継続的インテグレーション ビルドで奇妙なスレッドの問題に遭遇し、次のようになりました。
testThatDifferentArgumentsCanBeParsedConcurrently(se.softhouse.jargo.concurrency.ConcurrencyTest) Time elapsed: 0.479 sec <<< FAILURE!
org.junit.ComparisonFailure: expected:<... greeting phrase to [
]greet new connection...> but was:<... greeting phrase to []greet new connection...>:<... greeting phrase to []greet new connection...>
oraclejdkではなく、openjdkでのみ問題が発生するようです。
そして、BreakIterator を使用している私のコードは次のとおりです。
/**
* Wraps lines where <a
* href="http://docs.oracle.com/javase/tutorial/i18n/text/line.html">appropriate</a> (as defined
* by {@code locale}).
*
* @param value the value to separate with {@link StringsUtil#NEWLINE new lines}
* @param startingIndex the index where each line starts, useful for a fixed-size table for
* instance
* @param maxLineLength how long each line are allowed to be
*/
public static StringBuilder wrap(CharSequence value, int startingIndex, int maxLineLength, Locale locale)
{
String textToSplit = value.toString();
StringBuilder result = new StringBuilder(textToSplit.length());
// TODO(jontejj): is this not thread safe?
BreakIterator boundary = BreakIterator.getLineInstance(locale);
boundary.setText(textToSplit);
int start = boundary.first();
int end = boundary.next();
int lineLength = startingIndex;
while(end != BreakIterator.DONE)
{
String word = textToSplit.substring(start, end);
lineLength = lineLength + word.length();
if(lineLength >= maxLineLength)
{
result.append(NEWLINE);
lineLength = startingIndex;
}
result.append(word);
start = end;
end = boundary.next();
}
return result;
}
java.text.BreakIterator が本来の役割を果たさず、必要以上の文字数で行を引き延ばしたようです。
BreakIterator と RuleBasedBreakIterator の両方の openjdk バージョンを確認しましたが、明らかなスレッド セーフの問題は特定できませんでした。RuleBasedBreakIterator には、深く複製されていない配列がいくつかありますが、それらが変更されていることは確認できなかったので、安全であるはずです。oraclejdk のソース コードが見つかりませんでした。それらの間に以前ほど大きな違いがあってはならないというのは間違っていると思いましたか?
BreakIterator の使用に関する特定のテストで問題を切り分けようとしましたが、これまでのところ成果はありませんでした。
厄介な質問で申し訳ありませんが、私は立ち往生しているので、スタックオーバーフローの誰かが助けてくれると思いました。