调用数据库时应用程序冻结

时间:2014-11-27 06:23:48

标签: 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种方式调用。这是ItemListener附加到JComboBoxActionListener附加到JMenuComponentListener的。{/ p>

的ComponentListener

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

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


     }

的ItemListener

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

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

现在我的问题是,无论何时发生数据库调用,所有这些都有时会冻结。我认为它是线程问题的bcs,因此我将上述DisplayInitialRevenue_Thread作为测试调用displayInitialRevenue_Method()。然后我只调用了与调用此方法相关的区域,但有时它仍会冻结!我的其他数据库方法不在单独的线程中,但这是方法,所以为什么甚至调用“只”这个方法导致这个冻结?这是一个线程!

旁注,我使用的是MySQL服务器版本:5.6.16 - XAMPP附带的MySQL社区服务器(GPL)。

1 个答案:

答案 0 :(得分:2)

致电t.start()以开始新的Thread,呼叫Thread#run不再做任何事情,然后在同一线程上下文中调用run的{​​{1}}方法。 ..

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

有关详细信息,请参阅Worker Threads and SwingWorker

相关问题