Reputation: 1
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;
}
}
});
}
}
});
Upvotes: 0
Views: 890
Reputation: 1
executorService.shutdown(); solved the problem like below
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.execute(new Runnable() { });
executorService.shutdown();
Upvotes: 0
Reputation: 338211
I suggest you study the Executors tutorial by Oracle. And search Stack Overflow for many existing Questions and Answers on this topic.
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 schedulingYou are not scheduling your tasks with a delay. So you do not need a ScheduledExecutorService
.
You need only an ExecutorService
with a submit
method.
Upvotes: 0