Java:实现简单的连接池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/new_Aiden/article/details/72465666

数据库连接是非常珍贵的资源,能够复用则尽量复用。这里我们实现数据库连接。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class ConnectionPool {
    private List<ConnectionPair> connectionPairs;
    private static final int DEFAULT_SIZE = 16;
    private int size;

    public ConnectionPool(String url, String username, String password) {
        connectionPairs = new ArrayList<>(DEFAULT_SIZE);
        size = DEFAULT_SIZE;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            for (int i = 0; i < size; i++) {
                ConnectionPair pair = new ConnectionPair();
                pair.connection = DriverManager.getConnection(url, username, password);
                pair.isAvailable = true;
                connectionPairs.add(pair);
            }
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }

    // 同步获取connection,如果当前队列没有可用的connection,则阻塞
    public synchronized Connection getConnectionSync() {
        synchronized (this) {
            for (int i = 0; i < size; i++) {
                ConnectionPair pair = connectionPairs.get(i);
                if (pair.isAvailable) {
                    pair.isAvailable = false;
                    return pair.connection;
                }
            }
            // 进入阻塞态,等待可用的connection
            // 可以用while(true)代替,但是while(true)消耗CPU运算
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int i = 0; i < size; i++) {
                ConnectionPair pair = connectionPairs.get(i);
                if (pair.isAvailable) {
                    return pair.connection;
                }
            }
            return null;
        }
    }

    public synchronized Connection getConnection() {
        for (int i = 0; i < size; i++) {
            ConnectionPair pair = connectionPairs.get(i);
            if (pair.isAvailable) {
                pair.isAvailable = false;
                return pair.connection;
            }
        }
        return null;
    }

    public void releaseConnection(Connection connection) {
        for (int i = 0; i < size; i++) {
            ConnectionPair pair = connectionPairs.get(i);
            if (pair.connection == connection) {
                pair.isAvailable = true;
                synchronized (this) {
                    this.notifyAll();
                }
                break;
            }
        }
    }

    public void releaseAll() {
        for (int i = 0; i < size; i++) {
            try {
                connectionPairs.get(i).connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    private class ConnectionPair {
        Connection connection;
        boolean isAvailable;
    }
}

这里实现了getConnectionSync()和getConnection()方法。
我们来做下测试:

public class MainClass {

    public static void main(String[] args) throws Exception {
        ConnectionPool pool = new ConnectionPool(
                "jdbc:mysql://localhost:3306/mysql", "root", "");
        for (int i = 0; i < 35; i++) {
            Connection connection = pool.getConnectionSync();
            final int j = i;
            new Thread(() -> {
                System.out.println("获取了第" + j + "个连接:" + connection);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                pool.releaseConnection(connection);
                System.out.println("释放了第" + j + "个连接:" + connection);
            }).start();
        }
        pool.releaseAll();
    }
}

猜你喜欢

转载自blog.csdn.net/new_Aiden/article/details/72465666