为什么需要在ConnectionPool类中同步getConnection方法?

时间:2016-09-26 09:44:05

标签: java multithreading synchronization

我正在编写一个ObjectPool类来汇集Object实例。在查看Internet上的现有代码时,我看到getConnection方法已同步。我很困惑。为什么我们需要同步getConnection方法? 这是代码示例。

 public synchronized Connection getConnection() {
        Connection con = null;
        if (freeConnections.size() > 0) {
            // Pick the first Connection in the Vector
            // to get round-robin usage
            con = (Connection) freeConnections.firstElement();
            freeConnections.removeElementAt(0);
            try {
                if (con.isClosed()) {
                    log("Removed bad connection from " + name);
                    // Try again recursively
                    con = getConnection();
                }
            }
            catch (SQLException e) {
                log("Removed bad connection from " + name);
                // Try again recursively
                con = getConnection();
            }
        }
        else if (maxConn == 0 || checkedOut < maxConn) {
            con = newConnection();
        }
        if (con != null) {
            checkedOut++;
        }
        return con;
    }

我的意思是每个线程我们将创建一个ConnectionManager的新实例,它将从ConnectionPool获取连接。为什么我们需要ConnectionPool类中的synchronized方法?请解释。我很困惑。

4 个答案:

答案 0 :(得分:1)

withPathsGroupedBy()

想象一下,如果两个线程按以下顺序运行此代码:A1,A2,B1,B2,C1,C2。他们将获得与进程相同的连接(第一个连接),然后第二个线程将删除它们都没有采取的第二个连接(第二个连接)!

答案 1 :(得分:0)

因此需要同步多个线程的操作,并确保只有一个线程可以在给定时间点访问资源。

答案 2 :(得分:0)

因为getConnection方法被设计为与单个DataSource实例同时调用。所以它确保了DataSource的线程安全.Moreover JDBC不提供线程安全性。

通过线程安全我们的意思是资源在特定时间被分配给单个线程,并且当该线程使用时,没有人可以访问它。这种行为可以防止脏读/写。但是,同步化可以在类级别进行泛化,并且不需要是本地的。如果getConnection是在构造函数/初始化方法中使用它可以在程序中需要的地方调用它,只要它每次都正确关闭。在这种情况下,你不需要显式序列化。

答案 3 :(得分:0)

从JAVA建立与数据库的连接有不同的策略。主要是为了线程安全,您需要在ConnectionPool类中使getConnection同步。如果程序中有多个线程,则可能有多个线程可能同时调用getConnection。在这种情况下,除非你使其同步,否则它不能确保线程安全。

使用synchronized关键字后,它可确保单个线程访问您的getConnection,使其成为线程安全事件。

虽然在java docs中没有明确提到,但DataSource#getConnection方法被设计为在单个DataSource实例上同时调用。