英文:
Threads are not closing automatically
问题
以下是您提供的代码翻译后的部分:
// 监听操作
client.subscribe("/location/#", new IMqttMessageListener() {
public void messageArrived(final String topic, final MqttMessage message) throws Exception {
final String payload = new String(message.getPayload());
System.out.println("接收到操作 " + payload);
if (payload.startsWith("{\"location\":")) {
// 在另一个线程中执行操作,以允许 MQTT 客户端完成处理此消息并向服务器确认接收
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
public void run() {
if (payload.equals("")) return;
try {
JsonObject jsonObject = new Gson().fromJson(payload, JsonObject.class);
String fixTime = "", vehicleid = "", deviceTime = "", lat = "", lon = "", speed = "", alt = "", accuracy = "", bearing = "";
try {
String locationStr = jsonObject.get("location").toString();
locationStr = locationStr.substring(1, locationStr.length() - 1).trim();
locationStr = locationStr.replace("\\", "");
JsonObject locationJson = new Gson().fromJson(locationStr, JsonObject.class);
try {
long millis = Long.parseLong(locationJson.get("mTime").toString());
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
fixTime = df.format(cal.getTime());
} catch (Exception ex) {
}
lat = locationJson.get("mLatitude").toString();
lon = locationJson.get("mLongitude").toString();
alt = locationJson.get("mAltitude").toString();
speed = locationJson.get("mSpeed").toString();
accuracy = locationJson.get("mAccuracy").toString();
bearing = locationJson.get("mBearing").toString();
} catch (Exception ex) {
ex.printStackTrace();
}
try {
String entityStr = jsonObject.get("entity").toString();
JsonObject entityJson = new Gson().fromJson(entityStr, JsonObject.class);
vehicleid = entityJson.get("id").toString();
vehicleid = vehicleid.replace("\"", "");
} catch (Exception ex) {
ex.printStackTrace();
}
try {
String headerStr = jsonObject.get("header").toString();
JsonObject headerJson = new Gson().fromJson(headerStr, JsonObject.class);
String deviceTimeMsStr = headerJson.get("timestamp").toString();
long msTime = Long.parseLong(deviceTimeMsStr);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(msTime);
deviceTime = df.format(cal.getTime());
} catch (Exception ex) {
ex.printStackTrace();
}
Connection conn = null;
Statement stmt = null;
try {
String SQL = "INSERT INTO positions(protocol, deviceid, devicetime, fixtime, valid, latitude, longitude, altitude, speed, course, address, attributes, accuracy, network)";
SQL += " VALUES('osmand',(SELECT id FROM devices WHERE uniqueid = '" + vehicleid + "'),'" + deviceTime + "','" + fixTime + "',1," + lat + "," + lon + "," + alt + "," + speed + "," + bearing + ",'','','" + accuracy + "','')";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(MYSQL_SERVERURL, MYSQL_USERID, MYSQL_PASSWORD);
stmt = conn.createStatement();
stmt.executeUpdate(SQL);
System.out.println("执行 " + SQL);
return;
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (stmt != null)
conn.close();
} catch (SQLException se) {
}
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
return;
}
}
});
}
}
});
注意:这是您提供的代码的翻译部分,包含了其中的主要逻辑。如果您需要完整的翻译或进一步的帮助,请随时提问。
英文:
The started threads looks like not closing even after return from run(). In the left panel of Netbeans, it shows many number of "pool-xx-thread-1-running" and is increasing each time thread is executed. Below is my code:
// listen for operations
client.subscribe("/location/#", new IMqttMessageListener() {
public void messageArrived (final String topic, final MqttMessage message) throws Exception {
final String payload = new String(message.getPayload());
System.out.println("Received operation " + payload);
if (payload.startsWith("{\"location\":")) {
// execute the operation in another thread to allow the MQTT client to
// finish processing this message and acknowledge receipt to the server
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
public void run() {
if(payload.equals("")) return;
try {
JsonObject jsonObject = new Gson().fromJson(payload, JsonObject.class);
String fixTime="", vehicleid="", deviceTime="", lat="", lon="", speed="",alt="", accuracy="", bearing="";
try{
String locationStr=jsonObject.get("location").toString();
locationStr=locationStr.substring(1, locationStr.length()-1).trim();
locationStr=locationStr.replace("\\", "");
JsonObject locationJson = new Gson().fromJson(locationStr, JsonObject.class);
try{
long millis = Long.parseLong(locationJson.get("mTime").toString());
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis);
fixTime = df.format(cal.getTime());
}catch(Exception ex){
}
lat=locationJson.get("mLatitude").toString();
lon=locationJson.get("mLongitude").toString();
alt=locationJson.get("mAltitude").toString();
speed=locationJson.get("mSpeed").toString();
accuracy=locationJson.get("mAccuracy").toString();
bearing=locationJson.get("mBearing").toString();
}catch(Exception ex){
ex.printStackTrace();
}
try{
String entityStr = jsonObject.get("entity").toString();
JsonObject entityJson = new Gson().fromJson(entityStr, JsonObject.class);
vehicleid = entityJson.get("id").toString();
vehicleid = vehicleid.replace("\"", "");
}catch(Exception ex){
ex.printStackTrace();
}
try{
String headerStr=jsonObject.get("header").toString();
JsonObject headerJson = new Gson().fromJson(headerStr, JsonObject.class);
String deviceTimeMsStr = headerJson.get("timestamp").toString();
long msTime = Long.parseLong(deviceTimeMsStr);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(msTime);
deviceTime = df.format(cal.getTime());
}catch(Exception ex){
ex.printStackTrace();
}
Connection conn = null;
Statement stmt = null;
try{
String SQL = "INSERT INTO positions(protocol, deviceid, devicetime, fixtime, valid, latitude, longitude, altitude, speed, course, address, attributes, accuracy, network)";
SQL += " VALUES('osmand',(SELECT id FROM devices WHERE uniqueid = '" + vehicleid + "'),'" + deviceTime + "','" + fixTime + "',1," + lat + "," + lon + "," + alt + "," + speed + "," + bearing + ",'',''," + accuracy + ",'')";
Class.forName("com.mysql.jdbc.Driver");
conn =DriverManager.getConnection(MYSQL_SERVERURL, MYSQL_USERID, MYSQL_PASSWORD);
stmt = conn.createStatement();
stmt.executeUpdate(SQL);
System.out.println("Executed " + SQL);
return;
}catch(Exception ex){
ex.printStackTrace();
}finally {
try {
if(stmt != null)
conn.close();
} catch(SQLException se) {
}
try {
if(conn != null)
conn.close();
} catch(SQLException se) {
se.printStackTrace();
}
}
}catch(Exception ex){
ex.printStackTrace();
}
finally{
return;
}
}
});
}
}
});
答案1
得分: 0
我建议您学习Oracle的Executors教程。并在Stack Overflow上搜索关于这个主题的许多现有问题和答案。
仅创建一次执行器服务
不要重复调用Executors.newSingleThreadScheduledExecutor()
。每次调用都会创建一个线程池。您从未关闭它们。这些线程可能会继续运行,甚至在您的应用程序终止后也是如此。
您应该在应用程序中仅实例化执行器服务一次(通常情况下)。然后在您的应用程序中的某个地方保存返回的ScheduledExecutorService
对象。
当您有一个要在后台线程上运行的任务时,检索该现有对象并安排任务。
最终,您必须关闭执行器(及其支持的线程池)。
有关更多讨论,请参阅我在一个非常类似的问题上的这个答案。
ScheduledExecutorService
用于调度
您没有为任务设置延迟。因此,您不需要ScheduledExecutorService
。
您只需要一个带有submit
方法的ExecutorService
。
英文:
I suggest you study the Executors tutorial by Oracle. And search Stack Overflow for many existing Questions and Answers on this topic.
Create executor service only once
Do not repeatedly call Executors.newSingleThreadScheduledExecutor()
. Each call is creating a thread pool. You are never shutting them down. The threads continue, possibly even after your app terminates.
You should be instantiating the executor service only once in your app (generally). Then save the returned ScheduledExecutorService
object somewhere in your app.
When you have a task to be run on a background thread, retrieve that existing object and schedule the task.
Eventually you must shut down the executor (with its backing thread pool).
For more discussion, see this Answer of mine on a very similar Question.
ScheduledExecutorService
is for scheduling
You are not scheduling your tasks with a delay. So you do not need a ScheduledExecutorService
.
You need only an ExecutorService
with a submit
method.
答案2
得分: 0
executorService.shutdown(); 解决了以下问题:
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.execute(new Runnable() {
});
executorService.shutdown();
英文:
executorService.shutdown(); solved the problem like below
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
executorService.execute(new Runnable() {
});
executorService.shutdown();
专注分享java语言的经验与见解,让所有开发者获益!
评论