之前在自己写程序的时候,在处理数据库访问时,自己写了一个类来实现连接池,将数据库连接对象Connection放到List中,在需要用Connection 时用List.get(0) 方法。
为了能实现对于请求的大量访问, 使用了多线程,但是在数据库连接时出到了异常,报错如下:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.RangeCheck(ArrayList.java:547) at java.util.ArrayList.remove(ArrayList.java:387)
在数据库连接管理类中的主要属性如下:
1 private static DBConnPoolMgr instance; 2 private static HashMap<String, List<Connection>> pool; 3 private static int pCount; // pCount == sum( list.size in pool) 4 private ReqBean bean;
数据连接创建方法如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 private synchronized int createConnection() throws ClassNotFoundException, SQLException { 2 if (pCount >= ConfBean.getDbMaxPool()) { 3 System.out.println("ERR_DB_OP_POOL_FULL while create connection, pool size( pcount ) is: " + pCount); 4 return GlobalCode.ERR_DB_OP_POOL_FULL; 5 } 6 try { 7 8 String driver = bean.getDbDriver(); 9 String dburl = bean.getDbUrl(); 10 String user = bean.getDbUser(); 11 String pswd = bean.getDbPswd(); 12 if (null == dburl || null == user || null == pswd) { 13 System.out.println("ERR_DB_INI_AUTH while create connection"); 14 return GlobalCode.ERR_DB_INI_AUTH; 15 } 16 17 Class.forName(driver); 18 Connection conn = DriverManager.getConnection(dburl, user, pswd); 19 20 if (null != conn) { 21 List<Connection> list = new ArrayList<Connection>(); 22 pCount++; 23 list.add(conn); 24 String uuid = ObjectUtil.getDBUuid(dburl, user, pswd); 25 pool.put(uuid, list); 26 } 27 else { 28 System.out.println("error while create connection to database, in DBConnPoolMgr.createConnection, null == conn"); 29 return GlobalCode.ERR_DB_INI; 30 } 31 return GlobalCode.GLOBAL_SUCC_CODE; 32 } 33 catch (ClassNotFoundException e) { 34 e.printStackTrace(); 35 throw e; 36 // return GlobalCode.ERR_DB_INI_DRIVER; 37 } 38 catch (SQLException e) { 39 e.printStackTrace(); 40 throw e; 41 // return GlobalCode.ERR_DB_INI; 42 } 43 }
在获取连接时核心代码如下:
1 Connection conn = list.get(0); 2 list.remove(0); 3 pCount--; 4 return conn;
网上有许多人也遇到了类似的问题, 程序会抛出这个异常, 都说在创建List、Connection 之类的对象时要通过下面这种方法:
1 List<Connection> list = null; 2 list = class.method(para);
但实际上,这没有多大关系。
后来问题终于解决了, 是因为在多线程序访问时,并发访问 临界资源 导致的,可能是自己当时对多线程编程水平太差,没有想到这一点,后来是在getConnection 这些方法中添加了synchronized 关键字,后来的方法签名如下:
public synchronized Connection getConnection(String uuid) throws ClassNotFoundException, SQLException