0

我正在尝试设置一个线程,该线程每 100 毫秒循环一次,每次迭代都会查询 SQL 数据库中的表。这是我的公共静态无效主类中的内容。如何在侦听器之外定义连接并仅在循环中调用查询?

    // Database credentials
    final String url = "jdbc:mysql://192.168.0.0/";
    final String db = "db";
    final String driver = "com.mysql.jdbc.Driver";
    final String table = "table";
    public final Connection conn = null;

    // Define listner
    ActionListener taskPerformer = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            //...Perform a task...

            System.out.println("Reading Info.");
            try {
                Class.forName(driver);
                try {
                    conn = DriverManager.getConnection(url+db,"root","pass");
                    Statement st = (Statement) conn.createStatement();
                    String sql = "";
                    st.executeUpdate(sql);
                    conn.close();

                } catch (SQLException s) {
                    s.printStackTrace();
                    JOptionPane.showMessageDialog(null, "ERROR: Please try again!");
                }
            } catch (ClassNotFoundException cnfe){
                JOptionPane.showMessageDialog(null, "ERROR:");  
            }
        }
        };
    Timer timer = new Timer( 100 , taskPerformer);
    timer.setRepeats(true);
    timer.start();

    Thread.sleep(100);

}

现在它给了我以下错误:

线程“AWT-EventQueue-0”java.lang.Error 中的异常:未解决的编译问题:无法分配最终的局部变量 conn,因为它是在封闭类型中定义的

4

2 回答 2

1

你不想。根据 JDBC 规范,连接不是线程安全的。因此,没有理由或理由证明 Connection 变量不是线程本地的。为什么不是?

于 2012-07-07T05:16:52.453 回答
0

既然您对非直接问题有了答案,让我用您的直接问题来补充。你有这个:public final Connection conn = null;这没有任何意义。您已分配null给一个final变量。您可能已经添加final,因为编译器抱怨您在内部类中使用了非最终变量。您可能想要实现的是延迟初始化的单例。删除final修饰符,然后编写一个单独的同步函数来检索连接并根据需要对其进行初始化:

private Connection conn;
private synchronized Connection connection() {
  if (conn == null) conn = createConnection();
  return conn;
}

当然,您最好确保从不同时使用连接,但您的用例不需要这样做。这种简单的连接池方法的另一个问题是连接处于无效状态。

于 2012-07-07T08:32:01.367 回答