Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java连接池实现_Java_Database_Object_Connection_Pool - Fatal编程技术网

Java连接池实现

Java连接池实现,java,database,object,connection,pool,Java,Database,Object,Connection,Pool,你能看看我的连接池是否是一种可行的实现方法吗 public class ConnectionPool { private static List<DBConnection> pool = null; private static int available = 0; private ConnectionPool() {} public static DBConnection getConnection() { if (pool ==

你能看看我的连接池是否是一种可行的实现方法吗

public class ConnectionPool {
    private static List<DBConnection> pool = null;
    private static int available = 0;
    private ConnectionPool() {}

    public static DBConnection getConnection() {
        if (pool == null) {
             pool = new ArrayList<DBConnection>();
             for (int i = 0; i < 3; i++) {
                 try {
                    pool.add(new DBConnection());
                    available++;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
             }
        }
        if (pool.size() > 0) {
            available--;
            return pool.remove(available);
        } else {
            return null;
        }
    }

    public static void returnConnection(DBConnection c) {
        pool.add(c);
        available++;
    }
}
请告诉我,我需要有关此实施的反馈。谢谢

一些想法:

  • 您的代码不是线程安全的。也许可以做这个
  • getConnection()中的代码太多。惰性初始化真的是吗 需要吗
  • 可用是无用的,可以由pool.size()替换

    • 有一些问题使得此实现非常困难

      • 线程安全。如果多个线程与池一起工作会怎么样?您没有在读/写访问时锁定列表
      • 静态最大池大小为3个连接,也可以立即创建所有连接,无论是否需要。一种常见的策略是创建一组连接,并在需要时创建更多的连接,直到达到允许/配置的最大值
      • 您只有静态方法。应该可以有几个池,这意味着您需要
        ConnectionPool
        的实例
      • 无法将主机+数据库名+用户+密码传递给所创建的连接
      • 您不需要处理“断开”的连接—如果现有连接出现问题,您可能需要重新创建连接。这比我开始使用池之前所想的要重要得多
      • 使用配置值而不是静态值,请参见第2点
      • 最后:当然,自己写这篇文章是很有趣的,但是如果你需要一个项目池,选择一个现有的,比如或
      我肯定还有更多要指出的,但除非这些问题得到解决,否则继续下去是没有用的

      • 您的
        getConnection()
        方法需要更改为,以便仅检索
        Connection
        对象

        准备连接和池应该从getConnection()方法中删除,并以这样一种方式添加,即当第一次加载
        ConnectionPool
        类时

        此外,您还需要处理一些其他属性,如
        连接超时
        清除
        等,以使其适用于所有场景

        也要保证线程安全


      池实现的一个大问题是将裸连接传递给池的调用者。这意味着某人可以从您的池中获取连接,关闭它,然后将其返回到池中。这是坏的

      解决此问题的正常方法是使用委托包装返回连接对象,并使它们忽略对close方法的调用(或者更好的方法是,使close()安全地将底层连接返回到池)

      其他主要问题:

        如果在事务的中间返回连接,会发生什么情况?
      • 如果连接以某种方式损坏或断开,会发生什么情况?它会留在游泳池里吗

      总之,您应该重用现有的连接池实现,而不是编写自己的连接池实现。现在,许多Type4驱动程序都有自己的连接池,就在驱动程序中。

      其他成员已经提出了很多建议。我有一些模型实现,想和新访客分享。以下是代码:

      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Iterator;
      import java.util.concurrent.ConcurrentLinkedQueue;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ScheduledExecutorService;
      import java.util.concurrent.TimeUnit;
      
      abstract class ObjectPool<T> {
          private ConcurrentLinkedQueue<T> pool;
          ScheduledExecutorService executorService;
      
          ObjectPool(int minObjects) {
              pool = new ConcurrentLinkedQueue<T>();
              for (int i = 0; i < minObjects; i++) {
                  pool.add(createObject());
              }
          }
      
          ObjectPool(final int minObjects, final int maxSize, final long interval){
              pool = new ConcurrentLinkedQueue<T>();
              for (int i = 0; i < minObjects; i++) {
                  pool.add(createObject());
              }
      
              executorService = Executors.newSingleThreadScheduledExecutor();
              executorService.scheduleWithFixedDelay(new Runnable(){
      
                  public void run() {
                      int size = pool.size();
                      while(size > maxSize){
                          pool.remove();
                      }
                      Iterator i = pool.iterator();
                      while(i.hasNext()){
                          T t = (T) i.next();
                          if(checkExpiry(t)){
                              System.out.println("Expiry existed...");
                              i.remove();
                          }
                      }
      
                      while(pool.size() < minObjects){
                          System.out.println("Adding more objects to pool");
                          pool.add(createObject());
                      }
                  }
      
              }, interval, interval, TimeUnit.MILLISECONDS);
      
          }
      
          public T borrowObject() {
              if (pool.peek() == null)
                  return createObject();
              return pool.remove();
          }
      
          public void addObject(T obj) {
              if (obj == null)
                  return;
              pool.add(obj);
          }
      
          public abstract T createObject();
      
          public abstract boolean checkExpiry(T t);
      }
      
      class MultithreadQuery extends Thread{
          private ObjectPool<Connection> pool;
          private int threadNo;
          String query;
          MultithreadQuery(ObjectPool<Connection> pool,int threadNo, String query){
              this.pool = pool;
              this.threadNo = threadNo;
              this.query = query;
      
          }
          @Override
          public void run(){
              Connection con = pool.borrowObject();
              Statement stmt;
              try {
                  stmt = con.createStatement();
                  System.out.println("Query started for thread->"+ threadNo);
                  ResultSet rs=stmt.executeQuery(query);
                  while(rs.next())  
                  System.out.println(rs.getInt(1)+"  "+rs.getString(2)+"  "+rs.getString(3));
                  System.out.println("closing connection....");
                  con.close();
              } catch (SQLException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }  
              pool.addObject(con);        
              System.out.println("Query ended for thread->"+ threadNo);
          }
      }
      
      public class ObjectPoolPatternDemo {
          ObjectPool<Connection> pool;
      
          public void setUp(){
              pool = new ObjectPool<Connection>(4, 10, 1) {
      
                  @Override
                  public Connection createObject() {
                      Connection con;
                      try {
                          con = DriverManager.getConnection("URL","Username","Password");
                          return con;
                      } catch (SQLException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                      return null;
                  }
      
                  @Override
                  public boolean checkExpiry(Connection conn) {
                      boolean expiryFlag = false;
                      try {
                          if(conn.isClosed())
                              expiryFlag = true;
      
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                      return expiryFlag;
                  }
              };
          }
      
          public static void main(String[] args) throws SQLException {
              ObjectPoolPatternDemo oppd = new ObjectPoolPatternDemo();
              oppd.setUp();
      
              ExecutorService es = Executors.newFixedThreadPool(4);
              String query = "select * from TABLE";
              es.execute(new MultithreadQuery(oppd.pool,1,query));
              es.execute(new MultithreadQuery(oppd.pool,2,query));
              es.execute(new MultithreadQuery(oppd.pool,3,query));
              es.execute(new MultithreadQuery(oppd.pool,4,query));
              es.execute(new MultithreadQuery(oppd.pool,5,query));
              es.execute(new MultithreadQuery(oppd.pool,6,query));
      
              es.shutdown();
              try {
                  es.awaitTermination(1, TimeUnit.DAYS);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              System.out.println("finally completed...");
          }
      }
      
      
      导入java.sql.Connection;
      导入java.sql.DriverManager;
      导入java.sql.ResultSet;
      导入java.sql.SQLException;
      导入java.sql.Statement;
      导入java.util.Iterator;
      导入java.util.concurrent.ConcurrentLinkedQueue;
      导入java.util.concurrent.ExecutorService;
      导入java.util.concurrent.Executors;
      导入java.util.concurrent.ScheduledExecutorService;
      导入java.util.concurrent.TimeUnit;
      抽象类对象池{
      专用ConcurrentLinkedQueue池;
      ScheduledExecutorService执行器服务;
      对象池(int minObjects){
      池=新的ConcurrentLinkedQueue();
      对于(int i=0;i最大大小){
      pool.remove();
      }
      迭代器i=pool.Iterator();
      while(i.hasNext()){
      T=(T)i.next();
      如果(检查到期日(t)){
      System.out.println(“存在到期日…”);
      i、 删除();
      }
      }
      while(pool.size()启动查询”+threadNo);
      ResultSet rs=stmt.executeQuery(查询);
      while(rs.next())
      System.out.println(rs.getInt(1)+“”+rs.getString(2)+“”+
      
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Iterator;
      import java.util.concurrent.ConcurrentLinkedQueue;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      import java.util.concurrent.ScheduledExecutorService;
      import java.util.concurrent.TimeUnit;
      
      abstract class ObjectPool<T> {
          private ConcurrentLinkedQueue<T> pool;
          ScheduledExecutorService executorService;
      
          ObjectPool(int minObjects) {
              pool = new ConcurrentLinkedQueue<T>();
              for (int i = 0; i < minObjects; i++) {
                  pool.add(createObject());
              }
          }
      
          ObjectPool(final int minObjects, final int maxSize, final long interval){
              pool = new ConcurrentLinkedQueue<T>();
              for (int i = 0; i < minObjects; i++) {
                  pool.add(createObject());
              }
      
              executorService = Executors.newSingleThreadScheduledExecutor();
              executorService.scheduleWithFixedDelay(new Runnable(){
      
                  public void run() {
                      int size = pool.size();
                      while(size > maxSize){
                          pool.remove();
                      }
                      Iterator i = pool.iterator();
                      while(i.hasNext()){
                          T t = (T) i.next();
                          if(checkExpiry(t)){
                              System.out.println("Expiry existed...");
                              i.remove();
                          }
                      }
      
                      while(pool.size() < minObjects){
                          System.out.println("Adding more objects to pool");
                          pool.add(createObject());
                      }
                  }
      
              }, interval, interval, TimeUnit.MILLISECONDS);
      
          }
      
          public T borrowObject() {
              if (pool.peek() == null)
                  return createObject();
              return pool.remove();
          }
      
          public void addObject(T obj) {
              if (obj == null)
                  return;
              pool.add(obj);
          }
      
          public abstract T createObject();
      
          public abstract boolean checkExpiry(T t);
      }
      
      class MultithreadQuery extends Thread{
          private ObjectPool<Connection> pool;
          private int threadNo;
          String query;
          MultithreadQuery(ObjectPool<Connection> pool,int threadNo, String query){
              this.pool = pool;
              this.threadNo = threadNo;
              this.query = query;
      
          }
          @Override
          public void run(){
              Connection con = pool.borrowObject();
              Statement stmt;
              try {
                  stmt = con.createStatement();
                  System.out.println("Query started for thread->"+ threadNo);
                  ResultSet rs=stmt.executeQuery(query);
                  while(rs.next())  
                  System.out.println(rs.getInt(1)+"  "+rs.getString(2)+"  "+rs.getString(3));
                  System.out.println("closing connection....");
                  con.close();
              } catch (SQLException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }  
              pool.addObject(con);        
              System.out.println("Query ended for thread->"+ threadNo);
          }
      }
      
      public class ObjectPoolPatternDemo {
          ObjectPool<Connection> pool;
      
          public void setUp(){
              pool = new ObjectPool<Connection>(4, 10, 1) {
      
                  @Override
                  public Connection createObject() {
                      Connection con;
                      try {
                          con = DriverManager.getConnection("URL","Username","Password");
                          return con;
                      } catch (SQLException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                      return null;
                  }
      
                  @Override
                  public boolean checkExpiry(Connection conn) {
                      boolean expiryFlag = false;
                      try {
                          if(conn.isClosed())
                              expiryFlag = true;
      
                      } catch (SQLException e) {
                          e.printStackTrace();
                      }
                      return expiryFlag;
                  }
              };
          }
      
          public static void main(String[] args) throws SQLException {
              ObjectPoolPatternDemo oppd = new ObjectPoolPatternDemo();
              oppd.setUp();
      
              ExecutorService es = Executors.newFixedThreadPool(4);
              String query = "select * from TABLE";
              es.execute(new MultithreadQuery(oppd.pool,1,query));
              es.execute(new MultithreadQuery(oppd.pool,2,query));
              es.execute(new MultithreadQuery(oppd.pool,3,query));
              es.execute(new MultithreadQuery(oppd.pool,4,query));
              es.execute(new MultithreadQuery(oppd.pool,5,query));
              es.execute(new MultithreadQuery(oppd.pool,6,query));
      
              es.shutdown();
              try {
                  es.awaitTermination(1, TimeUnit.DAYS);
              } catch (InterruptedException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
              System.out.println("finally completed...");
          }
      }