diff --git a/src/share/classes/java/util/StringJoiner.java b/src/share/classes/java/util/StringJoiner.java index d2734102c672e2c845ffc9667a3f34564978ba3f..ac0cb89eca5fd65ff4b8d778a45b77e99afb37ae 100644 --- a/src/share/classes/java/util/StringJoiner.java +++ b/src/share/classes/java/util/StringJoiner.java @@ -206,11 +206,12 @@ public final class StringJoiner { public StringJoiner merge(StringJoiner other) { Objects.requireNonNull(other); if (other.value != null) { + final int length = other.value.length(); + // lock the length so that we can seize the data to be appended + // before initiate copying to avoid interference, especially when + // merge 'this' StringBuilder builder = prepareBuilder(); - StringBuilder otherBuilder = other.value; - if (other.prefix.length() < otherBuilder.length()) { - builder.append(otherBuilder, other.prefix.length(), otherBuilder.length()); - } + builder.append(other.value, other.prefix.length(), length); } return this; } diff --git a/test/java/util/StringJoiner/MergeTest.java b/test/java/util/StringJoiner/MergeTest.java index 79654612db77c84fa7e918b10131f51f1ce51edb..9361e9b3f0ef75754777b0bb64daf27746f4cb2b 100644 --- a/test/java/util/StringJoiner/MergeTest.java +++ b/test/java/util/StringJoiner/MergeTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 8017231 + * @bug 8017231 8020977 * @summary test StringJoiner::merge * @run testng MergeTest */ @@ -121,4 +121,13 @@ public class MergeTest { sj.merge(other); assertEquals(sj.toString(), "{a,b,c,d:e:f}"); } -} \ No newline at end of file + + public void testMergeSelf() { + final StringJoiner sj = new StringJoiner(",", "[", "]").add("a").add("b"); + assertEquals(sj.merge(sj).toString(), "[a,b,a,b]"); + assertEquals(sj.merge(sj).toString(), "[a,b,a,b,a,b,a,b]"); + + final StringJoiner sj2 = new StringJoiner(",").add("c").add("d"); + assertEquals(sj2.merge(sj2).toString(), "c,d,c,d"); + } +}