之前在自己写程序的时候,在处理数据库访问时,自己写了一个类来实现连接池,将数据库连接对象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;

 

数据连接创建方法如下:

View Code
 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
 posted on 2012-11-22 11:12  小枫晚归  阅读(2660)  评论(0编辑  收藏  举报