JSONObject toString 有时会抛出 ConcurrentModificationError
JSONObject toString sometimes throw a ConcurrentModificationError
首先,很抱歉无法提供我的代码。我创建了一个 JSONObject 并正在转换为字符串,我的 Android 应用程序有时会崩溃并出现以下错误。
E/AndroidRuntime( 6162): java.util.ConcurrentModificationException
E/AndroidRuntime( 6162): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
E/AndroidRuntime( 6162): at org.json.JSONArray.writeTo(JSONArray.java:612)
E/AndroidRuntime( 6162): at org.json.JSONStringer.value(JSONStringer.java:233)
E/AndroidRuntime( 6162): at org.json.JSONObject.writeTo(JSONObject.java:720)
E/AndroidRuntime( 6162): at org.json.JSONObject.toString(JSONObject.java:689)
根据我的研究,我无法说出为什么会出现 ConcurrentModificationException。我只有一个线程访问信息。我认为 toString() 不会执行任何删除操作。有人可以解释一下他们是否在 Android 中看到过任何此类问题,以及他们是如何对它进行排序的?
已编辑
根据@domi 的建议添加了稍作修改的代码。该问题一直出现在
行中
message.put("message", tempObject.toString());
private void message() {
if (this.jsonObject == null)
this.jsonObject = new JSONObject();
try {
TimeZone tz = TimeZone.getTimeZone("UTC");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
df.setTimeZone(tz);
Date date = new Date();
String dateString = df.format(date);
System.out.println(dateString);
jsonObject.put("Date", dateString);
JSONObject jsObj = new JSONObject();
jsObj.put("Cat", Cat.getInfo());
jsonObject.put("Cat", jsObj);
JSONArray tempInfo = getJsonArray(Dog.getInfo());
jsonObject.put("Dog", tempInfo);
} catch (JSONException e) {
e.printStackTrace();
}
TimeZone tz = TimeZone.getTimeZone("UTC");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
df.setTimeZone(tz);
Date date = new Date();
String dateString = df.format(date);
if (this.message == null)
this.message = new JSONObject();
try {
message.put("topic", topic);
JSONObject tempObject = new JSONObject();
synchronized(this.jsonObject) {
System.out.println("In lock" + dateString);
tempObject = this.jsonObject;
this.jsonObject = null;
}
message.put("message", tempObject.toString());
tempObject = null;
synchronized (this.message) {
doSomething(message);
}
System.out.println("Out lock");
} catch (JSONException e) {
e.printStackTrace();
} finally {
System.out.println(message);
}
}
我能够解决这个问题。问题是
message.put("message", tempObject.toString());
方法调用 tempObject.toString() 导致遍历列表(假设),而 message.put(...) 导致访问结果字符串。有时这会导致 ConcurrentModificationException。我能够通过分两行执行并锁定到位来解决它。
首先,很抱歉无法提供我的代码。我创建了一个 JSONObject 并正在转换为字符串,我的 Android 应用程序有时会崩溃并出现以下错误。
E/AndroidRuntime( 6162): java.util.ConcurrentModificationException
E/AndroidRuntime( 6162): at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
E/AndroidRuntime( 6162): at org.json.JSONArray.writeTo(JSONArray.java:612)
E/AndroidRuntime( 6162): at org.json.JSONStringer.value(JSONStringer.java:233)
E/AndroidRuntime( 6162): at org.json.JSONObject.writeTo(JSONObject.java:720)
E/AndroidRuntime( 6162): at org.json.JSONObject.toString(JSONObject.java:689)
根据我的研究,我无法说出为什么会出现 ConcurrentModificationException。我只有一个线程访问信息。我认为 toString() 不会执行任何删除操作。有人可以解释一下他们是否在 Android 中看到过任何此类问题,以及他们是如何对它进行排序的?
已编辑
根据@domi 的建议添加了稍作修改的代码。该问题一直出现在
行中message.put("message", tempObject.toString());
private void message() {
if (this.jsonObject == null)
this.jsonObject = new JSONObject();
try {
TimeZone tz = TimeZone.getTimeZone("UTC");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
df.setTimeZone(tz);
Date date = new Date();
String dateString = df.format(date);
System.out.println(dateString);
jsonObject.put("Date", dateString);
JSONObject jsObj = new JSONObject();
jsObj.put("Cat", Cat.getInfo());
jsonObject.put("Cat", jsObj);
JSONArray tempInfo = getJsonArray(Dog.getInfo());
jsonObject.put("Dog", tempInfo);
} catch (JSONException e) {
e.printStackTrace();
}
TimeZone tz = TimeZone.getTimeZone("UTC");
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'", Locale.US);
df.setTimeZone(tz);
Date date = new Date();
String dateString = df.format(date);
if (this.message == null)
this.message = new JSONObject();
try {
message.put("topic", topic);
JSONObject tempObject = new JSONObject();
synchronized(this.jsonObject) {
System.out.println("In lock" + dateString);
tempObject = this.jsonObject;
this.jsonObject = null;
}
message.put("message", tempObject.toString());
tempObject = null;
synchronized (this.message) {
doSomething(message);
}
System.out.println("Out lock");
} catch (JSONException e) {
e.printStackTrace();
} finally {
System.out.println(message);
}
}
我能够解决这个问题。问题是
message.put("message", tempObject.toString());
方法调用 tempObject.toString() 导致遍历列表(假设),而 message.put(...) 导致访问结果字符串。有时这会导致 ConcurrentModificationException。我能够通过分两行执行并锁定到位来解决它。