mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-9240 Fixed a cloning problem in DecimalFormat which prevent formatToCharacterIterator to work properly in mulitple threads.
X-SVN-Rev: 31796
This commit is contained in:
parent
78c726c30b
commit
faba943de0
2 changed files with 64 additions and 0 deletions
|
@ -3508,6 +3508,7 @@ public class DecimalFormat extends NumberFormat {
|
|||
if (currencyPluralInfo != null) {
|
||||
other.currencyPluralInfo = (CurrencyPluralInfo) currencyPluralInfo.clone();
|
||||
}
|
||||
other.attributes = new ArrayList<FieldPosition>(); // #9240
|
||||
|
||||
// TODO: We need to figure out whether we share a single copy of DigitList by
|
||||
// multiple cloned copies. format/subformat are designed to use a single
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
package com.ibm.icu.dev.test.format;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
|
@ -2930,4 +2931,66 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test case for #9240
|
||||
* ICU4J 49.1 DecimalFormat did not clone the internal object holding
|
||||
* formatted text attribute information properly. Therefore, DecimalFormat
|
||||
* created by cloning may return incorrect results or may throw an exception
|
||||
* when formatToCharacterIterator is invoked from multiple threads.
|
||||
*/
|
||||
public void TestFormatToCharacterIteratorThread() {
|
||||
final int COUNT = 10;
|
||||
|
||||
DecimalFormat fmt1 = new DecimalFormat("#0");
|
||||
DecimalFormat fmt2 = (DecimalFormat)fmt1.clone();
|
||||
|
||||
int[] res1 = new int[COUNT];
|
||||
int[] res2 = new int[COUNT];
|
||||
|
||||
Thread t1 = new Thread(new FormatCharItrTestThread(fmt1, 1, res1));
|
||||
Thread t2 = new Thread(new FormatCharItrTestThread(fmt2, 100, res2));
|
||||
|
||||
t1.start();
|
||||
t2.start();
|
||||
|
||||
try {
|
||||
t1.join();
|
||||
t2.join();
|
||||
} catch (InterruptedException e) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
int val1 = res1[0];
|
||||
int val2 = res2[0];
|
||||
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
if (res1[i] != val1) {
|
||||
errln("Inconsistent first run limit in test thread 1");
|
||||
}
|
||||
if (res2[i] != val2) {
|
||||
errln("Inconsistent first run limit in test thread 2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FormatCharItrTestThread implements Runnable {
|
||||
private NumberFormat fmt;
|
||||
private int num;
|
||||
private int[] result;
|
||||
|
||||
FormatCharItrTestThread(NumberFormat fmt, int num, int[] result) {
|
||||
this.fmt = fmt;
|
||||
this.num = num;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
AttributedCharacterIterator acitr = fmt.formatToCharacterIterator(num);
|
||||
acitr.first();
|
||||
result[i] = acitr.getRunLimit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue