线程不会自动关闭。

huangapple 未分类评论49阅读模式
英文:

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;
                        }
                    }
                });
            }
        }
    });

screenshot

答案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();

huangapple
  • 本文由 发表于 2020年4月7日 13:28:03
  • 转载请务必保留本文链接:https://java.coder-hub.com/61073347.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定