java - 调用数据库时应用程序卡住

标签 java mysql multithreading swing freeze

我在 Java 的 ComponentAdapter 中实现了很多东西。由于它确实从数据库加载数据并显示在 JTable 中,因此我将其添加到另一个线程中。我将向您展示一种由此类 ComponentAdapter

调用的方法
private class DisplayInitialRevenue_Thread implements Runnable
     {

        @Override
        public void run() 
        {
            displayInitialRevenue_Method();
        }

     }

     private void displayInitialRevenue_Method()
     {
        //Get the dates from the combo
        String selectedCouple = revenueYearCombo.getSelectedItem().toString();

        if(selectedCouple.equals("Select Year"))
        {
            return;
        }

        String[] split = selectedCouple.split("/");


         //Related to DB
         double totalamountInvested;



             //Get data from the database
             dbConnector = new DBHandler();
             dbConnector.makeConnection();

             DefaultTableModel model = (DefaultTableModel) initialRevenueTable.getModel();
             model.setRowCount(0);



             ResultSet selectAllDetails = dbConnector.selectAllDetails("SQL CODE HERE ");

             try
             {
                 if(selectAllDetails.isBeforeFirst()==false)
                 {
                     JOptionPane.showMessageDialog(null,"This table is empty");
                 }
                 else
                 {
                     while(selectAllDetails.next())
                     {
                         String clientName = selectAllDetails.getString("Client Name");
                         String providerName = selectAllDetails.getString("Provider Name");
                         Double amountInvested = selectAllDetails.getDouble("Invest_Amount");


                        //Get Other Data


                         //Update the table
                         Object[]row = {dateS,clientName,providerName,amountInvested};

                         model.addRow(row);

                         //Get the total
                         amountInvested = amountInvested+amountInvested;

                     }

                     //Add the sum
                     Object[]blankRow = {null,null,null,null};
                     model.addRow(blankRow);

                      Object[]row = {dateS,clientName,providerName,amountInvested};
                 }
             }
             catch(SQLException sql)
             {
                 JOptionPane.showMessageDialog(null,sql.getLocalizedMessage());
             }
     }

而且,上面的线程可以通过 3 种方式调用。即通过附加到 JComboBoxItemListener、附加到 JMenuActionListenerComponentListener >.

组件监听器

private class DisplayInitialRevenue extends ComponentAdapter
     {
         public void componentShown(ComponentEvent e) 
         {
             formMemorizer = FormMemorizer.Initial_Revenue;
             //displayInitialRevenue_Method();

             DisplayInitialRevenue_Thread t = new DisplayInitialRevenue_Thread();
             t.run();
         }


     }

项目监听器

private class RevenueYearComboAction implements ItemListener
     {

        @Override
        public void itemStateChanged(ItemEvent e) 
        {
            if(e.getStateChange() == ItemEvent.SELECTED)
            {
                int selection = formMemorizer;

                if(selection==-1)
                {
                    return;
                }
                else if(selection==FormMemorizer.Initial_Revenue)
                {
                    //displayInitialRevenue_Method();
                    DisplayInitialRevenue_Thread t = new DisplayInitialRevenue_Thread();
                    t.run();
                }
        }
}

我有很多这样的方法来从数据库获取数据并提供给 JTables,从 GUI 获取数据并保存在数据库中。

现在我的问题是,每当发生数据库调用时,所有这些有时都会卡住。我认为这是线程问题的原因,所以我做了上面的 DisplayInitialRevenue_Thread 来调用 displayInitialRevenue_Method() 作为测试。然后我只调用了与调用此方法相关的区域,但有时它仍然卡住!我的其他数据库方法不在单独的线程中,但这是方法,那么为什么即使“仅”调用此方法也会导致该方法卡住?它在一个线程中!

顺便说一下,我使用的是 Java 8,使用 MySQL 服务器版本:5.6.16 - XAMPP 附带的 MySQL Community Server (GPL)。

最佳答案

调用t.start()启动一个新的Thread,调用Thread#run什么也不做,然后调用run同一线程上下文中 Thread 方法...

话虽如此,Swing 不是线程安全的,Swing 要求对 UI 的所有更新都在事件调度线程的上下文中进行。您应该考虑使用 SwingWorker,而不是使用 Thread,它允许您在后台线程中执行长时间运行的任务,但它提供了易于使用的 publish /process 方法并在完成时调用 done,这些方法是在 EDT 的上下文中为您执行的。

参见Worker Threads and SwingWorker了解更多详情

关于java - 调用数据库时应用程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27164311/

相关文章:

mysql - 不确定这个右外连接的结果是什么

c++ - RC 在多线程/多处理上下文中代表什么?

c# - 如何在非常大的输入上没有中间文件的情况下使用 GZipStream 进行多线程压缩/解压缩

java - 在java中初始化对象A等于另一个对象B

mysql - 即使使用 Alias,MySQL 中的列也不明确

java - 如何使用 Java 删除 PDF 文件的第一页?

php - 插入时连接字符串和主键 Id

Python:有没有一种线程安全的方法来知道lock.acquire()是否已阻塞(并继续阻塞)?

java - 以linux风格定义的路径是一个最终变量。 windows下打不开路径

java - GAE 存储到数据库但不显示在 View 上