Java - 阻止 GSON 创建一个额外的线程
Java - stop GSON from creating an additional thread
我正在 Java 中编写一些小代码片段,以便在移动应用程序后端服务器上 运行。我使用的服务器有一个线程的限制,所以我写的代码基本上需要同步和单线程。
我正在使用 gson 解析从第三方 API 检索到的 JSON,一些示例代码如下:
public class JSONWorker {
public double getJSONFromURL(String sURL){
JsonParser jp = new JsonParser(); //from gson
JsonElement root = null;
// Connect to the URL using java's native library
URL url = null;
try {
url = new URL(sURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection request = null;
try {
request = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
request.connect();
} catch (IOException e) {
e.printStackTrace();
}
try {
root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
} catch (IOException e) {
e.printStackTrace();
}
JsonObject rootobj = root.getAsJsonObject();
String price = rootobj.get("lastPrice").getAsString();
return Double.parseDouble(price);
}
}
返回的错误表明我没有创建额外线程的权限,并指向此特定行作为问题:
root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
gson 中的 JSON 解析器应该创建一个额外的线程是否正确?
这可能与它在远程服务器上 运行ning 这一事实有关吗?
有没有办法强制 gson 或特别是解析器 synchronous/single 线程化?
编辑:完整错误输出
[ERROR] You have no permission to create thread in CodeRunner secure group.
java.lang.reflect.InvocationTargetException: null
at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.backendless.coderunner.runtime.task.TimerInvocationTask.runImpl(TimerInvocationTask.java:52)
at com.backendless.coderunner.runtime.executor.ExtendedRunnable.run(ExtendedRunnable.java:39)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.AccessControlException: You have no permission to create thread in CodeRunner secure group.
at com.backendless.coderunner.runtime.security.CodeRunnerSecurityManager.checkAccess(CodeRunnerSecurityManager.java:48)
at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
at java.lang.ThreadGroup.getParent(ThreadGroup.java:167)
at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:102)
at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:96)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.http.KeepAliveCache.put(KeepAliveCache.java:95)
at sun.net.www.protocol.https.HttpsClient.putInKeepAliveCache(HttpsClient.java:659)
at sun.net.www.http.HttpClient.finished(HttpClient.java:395)
at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:97)
at sun.net.www.MeteredStream.justRead(MeteredStream.java:93)
at sun.net.www.MeteredStream.read(MeteredStream.java:135)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3393)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.consumeNonExecutePrefix(JsonReader.java:1576)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:534)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.Streams.parse(Streams.java:46)
at com.google.gson.JsonParser.parse(JsonParser.java:84)
at com.google.gson.JsonParser.parse(JsonParser.java:59)
at com.myApp.timers.PriceGetterTimer.execute(PriceGetterTimer.java:100)
... 6 common frames omitted
干杯,
米奇
这里的问题似乎不是 gson
,而是 request.getContent()
。
在许多情况下,将某种数据流转换为 InputStream
需要它自己的线程。也许数据是从网站流入的,并由网络通信层缓冲。使用线程可以最有效地实现将其即时转换为流。
话题由 built-in KeepAliveCache
创建。
您可以指定请求 header Connection
的值为 Close
或将系统 属性 http.keepAlive
设置为值 false
像这样(在你实际打开连接之前):
System.setProperty("http.keepAlive", "false");
可以找到更多信息here
我正在 Java 中编写一些小代码片段,以便在移动应用程序后端服务器上 运行。我使用的服务器有一个线程的限制,所以我写的代码基本上需要同步和单线程。
我正在使用 gson 解析从第三方 API 检索到的 JSON,一些示例代码如下:
public class JSONWorker {
public double getJSONFromURL(String sURL){
JsonParser jp = new JsonParser(); //from gson
JsonElement root = null;
// Connect to the URL using java's native library
URL url = null;
try {
url = new URL(sURL);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection request = null;
try {
request = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
request.connect();
} catch (IOException e) {
e.printStackTrace();
}
try {
root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
} catch (IOException e) {
e.printStackTrace();
}
JsonObject rootobj = root.getAsJsonObject();
String price = rootobj.get("lastPrice").getAsString();
return Double.parseDouble(price);
}
}
返回的错误表明我没有创建额外线程的权限,并指向此特定行作为问题:
root = jp.parse(new InputStreamReader((InputStream) request.getContent()));
gson 中的 JSON 解析器应该创建一个额外的线程是否正确? 这可能与它在远程服务器上 运行ning 这一事实有关吗? 有没有办法强制 gson 或特别是解析器 synchronous/single 线程化?
编辑:完整错误输出
[ERROR] You have no permission to create thread in CodeRunner secure group.
java.lang.reflect.InvocationTargetException: null
at sun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.backendless.coderunner.runtime.task.TimerInvocationTask.runImpl(TimerInvocationTask.java:52)
at com.backendless.coderunner.runtime.executor.ExtendedRunnable.run(ExtendedRunnable.java:39)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.AccessControlException: You have no permission to create thread in CodeRunner secure group.
at com.backendless.coderunner.runtime.security.CodeRunnerSecurityManager.checkAccess(CodeRunnerSecurityManager.java:48)
at java.lang.ThreadGroup.checkAccess(ThreadGroup.java:315)
at java.lang.ThreadGroup.getParent(ThreadGroup.java:167)
at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:102)
at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:96)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.http.KeepAliveCache.put(KeepAliveCache.java:95)
at sun.net.www.protocol.https.HttpsClient.putInKeepAliveCache(HttpsClient.java:659)
at sun.net.www.http.HttpClient.finished(HttpClient.java:395)
at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:97)
at sun.net.www.MeteredStream.justRead(MeteredStream.java:93)
at sun.net.www.MeteredStream.read(MeteredStream.java:135)
at java.io.FilterInputStream.read(FilterInputStream.java:133)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(HttpURLConnection.java:3393)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.consumeNonExecutePrefix(JsonReader.java:1576)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:534)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.Streams.parse(Streams.java:46)
at com.google.gson.JsonParser.parse(JsonParser.java:84)
at com.google.gson.JsonParser.parse(JsonParser.java:59)
at com.myApp.timers.PriceGetterTimer.execute(PriceGetterTimer.java:100)
... 6 common frames omitted
干杯, 米奇
这里的问题似乎不是 gson
,而是 request.getContent()
。
在许多情况下,将某种数据流转换为 InputStream
需要它自己的线程。也许数据是从网站流入的,并由网络通信层缓冲。使用线程可以最有效地实现将其即时转换为流。
话题由 built-in KeepAliveCache
创建。
您可以指定请求 header Connection
的值为 Close
或将系统 属性 http.keepAlive
设置为值 false
像这样(在你实际打开连接之前):
System.setProperty("http.keepAlive", "false");
可以找到更多信息here