当前位置: 首页 > 知识库问答 >
问题:

线程不会自动关闭

蒯华彩
2023-03-14
            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个答案

宦博超
2023-03-14

我建议您学习Oracle的Executors教程。和搜索堆栈溢出,查找关于此主题的许多现有问题和答案。

不要重复调用executors.newsinglethreadscheduledexecutor()。每个调用都在创建一个线程池。你永远不会关闭它们。线程仍在继续,甚至可能在应用程序终止之后。

您应该只在应用程序中实例化executor服务一次(通常)。然后将返回的ScheduledExecutorService对象保存在应用程序的某个位置。

当有任务要在后台线程上运行时,检索现有对象并安排任务。

最后,您必须关闭executor(及其支持线程池)。

关于更多的讨论,请参见我对一个非常相似的问题的回答。

 类似资料:
  • 在下面的代码中,线程。activeCount()始终返回2,即使executor中的线程在5秒后终止。 我期望Thread.activeCount()在5秒后返回1。为什么它总是返回2?

  • 问题内容: 我有一个Python程序,当我使用退出应用程序时 ,脚本不会关闭。我的过程仍显示在运行的过程中。 为什么python线程不能关闭? 问题答案: 您需要将该线程设为守护程序线程。为此,请在调用线程的init之后添加以下行 当只有守护程序线程处于活动状态时,程序将退出,主线程当然是非守护程序的

  • 我正在后台线程中运行数学计算。试图在UITextView中实时发布结果。但是,在后台线程完成之前,结果不会显示。为什么不呢? 我在后台启动了一个方法, 背景线程方法的形式为, 在我开始尝试滚动视图之前,这其实不是什么大问题。慢得令人痛苦。因此,我创建了一个NSTimer来定期滚动UITextView。但是,即使计时器弹出并且方法运行以请求滚动,UITextView也不会滚动,直到后台方法完成。

  • 我的异步方法有问题。它工作正常,但线程数一直在增加。 下面是我的代码示例: 位于GitHub的完整项目:https://github.com/rublin/KarboMarketplaceExplorer 直接链接到类 下面是一个测试,涵盖了这种行为。

  • 当业务线程池满时,我们需要知道线程都在等待哪些资源、条件,以找到系统的瓶颈点或异常点。dubbo通过Jstack自动导出线程堆栈来保留现场,方便排查问题 默认策略: 导出路径,user.home标识的用户主目录 导出间隔,最短间隔允许每隔10分钟导出一次 指定导出路径: # dubbo.properties dubbo.application.dump.directory=/tmp <dubbo

  • 问题内容: 我的问题是这样的: 即使读取完成(数百万行)的文件后,如何仍能使该线程保持活动状态 问题是我有一个从javafx应用程序线程启动的线程,然后该线程(新线程)对文本文件执行一些读/写操作,当面对巨大的文件以进行解析时,它不会自然退出,需要花费一千七百万具体来说,行大。 我假设这是由于线程保留了我所缺少的某些资源,但是,由于我使用的是try-with-resource模型,所以我不确定这是