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 {
if (nextElement != null) { synchronized (lock) {
JsonElement returnValue = nextElement; if (nextElement != null) {
nextElement = null; JsonElement returnValue = nextElement;
return returnValue; nextElement = null;
return returnValue;
}
} }
try { try {
return parser.parse(); return parser.parse();
} catch (TokenMgrError e) { } catch (TokenMgrError e) {
@ -84,12 +105,14 @@ public final class JsonStreamParser implements Iterator<JsonElement> {
} }
public boolean hasNext() { public boolean hasNext() {
try { synchronized (lock) {
nextElement = next(); try {
return true; nextElement = next();
} catch (NoSuchElementException e) { return true;
nextElement = null; } catch (NoSuchElementException e) {
return false; nextElement = null;
return false;
}
} }
} }