Skip to content
This repository was archived by the owner on Dec 19, 2024. It is now read-only.

Commit 16d3579

Browse files
authored
Merge pull request #80 from tlrx/utf8writers
Fix UTF8Writer when used in same thread
2 parents c5d013c + 7e78903 commit 16d3579

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

src/main/java/com/fasterxml/jackson/dataformat/yaml/UTF8Writer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public UTF8Writer(OutputStream out)
4343
_bufferHolder = _findBufferHolder();
4444
byte[] buffer = _bufferHolder[0];
4545
if (buffer == null) {
46-
_bufferHolder[0] = buffer = new byte[DEFAULT_BUFFER_SIZE];
46+
buffer = new byte[DEFAULT_BUFFER_SIZE];
4747
} else {
4848
_bufferHolder[0] = null;
4949
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.fasterxml.jackson.dataformat.yaml;
2+
3+
import org.junit.Test;
4+
5+
import java.io.ByteArrayOutputStream;
6+
import java.io.IOException;
7+
import java.nio.charset.StandardCharsets;
8+
import java.util.concurrent.CopyOnWriteArrayList;
9+
import java.util.concurrent.CountDownLatch;
10+
11+
import static junit.framework.TestCase.assertTrue;
12+
import static org.junit.Assert.assertArrayEquals;
13+
import static org.junit.Assert.assertEquals;
14+
15+
public class UTF8WriterTest {
16+
17+
@Test
18+
public void canUseMultipleUTF8WritersInSameThread() throws IOException {
19+
final String message1 = "First message";
20+
final String message2 = "Second message";
21+
22+
ByteArrayOutputStream output1 = new ByteArrayOutputStream();
23+
ByteArrayOutputStream output2 = new ByteArrayOutputStream();
24+
25+
try (UTF8Writer first = new UTF8Writer(output1)) {
26+
first.write("First ");
27+
28+
try (UTF8Writer second = new UTF8Writer(output2)) {
29+
second.write("Second ");
30+
first.write("message");
31+
second.write("message");
32+
}
33+
}
34+
35+
assertArrayEquals(message1.getBytes(StandardCharsets.UTF_8), output1.toByteArray());
36+
assertArrayEquals(message2.getBytes(StandardCharsets.UTF_8), output2.toByteArray());
37+
}
38+
39+
@Test
40+
public void canUseMultipleUTF8WritersInParallelThread() throws Exception {
41+
final int size = 1_000;
42+
final Thread[] threads = new Thread[5];
43+
final ByteArrayOutputStream[] outputs = new ByteArrayOutputStream[threads.length];
44+
final CountDownLatch latch = new CountDownLatch(1);
45+
46+
// Starts multiple threads in parallel, each thread uses its own UTF8Writer to
47+
// write ${size} times the same number. For example, thread 0 writes 1000 times
48+
// the string "0". It is then trivial to check the resulting output.
49+
final CopyOnWriteArrayList<Exception> exceptions = new CopyOnWriteArrayList<>();
50+
for (int i = 0; i < threads.length; i++) {
51+
final ByteArrayOutputStream output = new ByteArrayOutputStream();
52+
final String number = String.valueOf(i);
53+
outputs[i] = output;
54+
threads[i] = new Thread() {
55+
@Override
56+
public void run() {
57+
UTF8Writer writer = null;
58+
try {
59+
latch.await();
60+
writer = new UTF8Writer(output);
61+
for (int j = 0; j < size; j++) {
62+
writer.write(number);
63+
}
64+
} catch (Exception e) {
65+
exceptions.add(e);
66+
} finally {
67+
if (writer != null) {
68+
try {
69+
writer.close();
70+
} catch (IOException e) {
71+
exceptions.add(e);
72+
}
73+
}
74+
}
75+
}
76+
};
77+
threads[i].start();
78+
}
79+
80+
latch.countDown();
81+
for (Thread thread : threads) {
82+
thread.join();
83+
}
84+
assertEquals(0, exceptions.size());
85+
86+
for (int i = 0; i < outputs.length; i++) {
87+
String result = new String(outputs[i].toByteArray(), StandardCharsets.UTF_8);
88+
assertEquals(size, result.length());
89+
assertTrue(result.matches(String.valueOf(i) + "{" + String.valueOf(size) + "}"));
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)