Add some synchronization to the JsonStreamParser to ensure that the "next" method behaves according to the API.

This commit is contained in:
Joel Leitch 2009-10-02 20:21:19 +00:00
parent 912db55ba6
commit 25ea878f66

View File

@ -23,7 +23,23 @@ import java.util.NoSuchElementException;
/** /**
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader * A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously. This class is not thread-safe. * asynchronously.
*
* <p>This class is thread-compatible. For some more literature on these definitions, refer to
* Effective Java.
*
* <p>To properly use this class across multiple thread, you will need to add some external
* synchronization to your classes/thread to get this to work properly. For example:
*
* <pre>
* JsonStreamParser parser = new JsonStreamParser("blah blah blah");
* JsonElement element;
* synchronized (someCommonObject) {
* if (parser.hasNext()) {
* element = parser.next();
* }
* }
* </pre>
* *
* @author Inderjeet Singh * @author Inderjeet Singh
* @author Joel Leitch * @author Joel Leitch
@ -32,6 +48,7 @@ import java.util.NoSuchElementException;
public final class JsonStreamParser implements Iterator<JsonElement> { public final class JsonStreamParser implements Iterator<JsonElement> {
private final JsonParserJavacc parser; private final JsonParserJavacc parser;
private final Object lock;
private JsonElement nextElement; private JsonElement nextElement;
/** /**
@ -48,6 +65,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
*/ */
public JsonStreamParser(Reader reader) { public JsonStreamParser(Reader reader) {
parser = new JsonParserJavacc(reader); parser = new JsonParserJavacc(reader);
lock = new Object();
nextElement = null; nextElement = null;
} }
@ -59,11 +77,14 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
* @since 1.4 * @since 1.4
*/ */
public JsonElement next() throws JsonParseException { public JsonElement next() throws JsonParseException {
synchronized (lock) {
if (nextElement != null) { if (nextElement != null) {
JsonElement returnValue = nextElement; JsonElement returnValue = nextElement;
nextElement = null; nextElement = null;
return returnValue; return returnValue;
} }
}
try { try {
return parser.parse(); return parser.parse();
} catch (TokenMgrError e) { } catch (TokenMgrError e) {
@ -84,6 +105,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
} }
public boolean hasNext() { public boolean hasNext() {
synchronized (lock) {
try { try {
nextElement = next(); nextElement = next();
return true; return true;
@ -92,6 +114,7 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
return false; return false;
} }
} }
}
public void remove() { public void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();