/**
     * retrieve all table names of databases
     * @param projPath
     * @param maxThread    max number of thread
     * @return
     */
    public static List<DBInfo> retreiveAllTables(String projPath, int maxThread) {
            ExecutorService threadPool = Executors.newCachedThreadPool();
            final ConcurrentLinkedQueue<DBInfo> queue = new ConcurrentLinkedQueue<DBInfo>();
            ArrayList<DBInfo> dbInfos = null;
            try {                dbInfos = new ArrayList<DBInfo>(getDBInfos(projPath)); //get all the dbinfo of the project without table name information                Collections.sort(dbInfos, new Comparator<DBInfo>() {
                    public int compare(DBInfo o1, DBInfo o2) {
                        return o1.getType().compareTo(o2.getType());
                    }
                });                ListUtil.putToQueue(dbInfos, queue);//put list's elements into a queue
            } catch (ConfigurationException e) {
                log.error(e, e);
            }            ArrayList<Callable<Object>> threads = new ArrayList<Callable<Object>>();
            for (int i = 0; i < maxThread; i++) {
                threads.add(new Callable<Object>() {
                    public Object call() throws Exception {
                        while (true) {
                            DBInfo dbInfo = queue.poll();
                            if (dbInfo == null) {
                                return null;
                            } else {
                                log.debug("thread fetching table: "+Thread.currentThread().getName()+", "+dbInfo.getName());
                                retreiveTables(dbInfo); //retreive all table names from the database of the dbinfo
                            }
                        }
                    }
                });
            }            try {
                threadPool.invokeAll(threads);
                threadPool.shutdown();
            } catch (InterruptedException e) {
                log.error(e, e);
            }            return dbInfos;
        }    public static void retreiveTables(DBInfo dbInfo) throws SQLException {
        Connection tempConn = null;
        try {
            tempConn = ConnFactory.getConnection(dbInfo.getType(), dbInfo.getConnUrl(),
                    dbInfo.getUserName(), dbInfo.getPassword());
        } catch (ClassNotFoundException e) {
            log.error(e, e);
        } catch (IllegalAccessException e) {
            log.error(e, e);
        } catch (InstantiationException e) {
            log.error(e, e);
        }
        retreiveTables(tempConn.getMetaData(), dbInfo);
    }
    public static void retreiveTables(DatabaseMetaData dmd, DBInfo dbInfo) throws SQLException {
        String[] types = {"TABLE"};
        ResultSet resultSet = null;        if (dbInfo.getType().equals("oracle") || dbInfo.getType().equals("mysql")) {
            resultSet = dmd.getTables(null, dbInfo.getUserName().toUpperCase(), "%", types);
        } else {
            resultSet = dmd.getTables(null, null, "%", types);
        }
        // Get the table names
        while (resultSet.next()) {
            // Get the table name
            String tableName = resultSet.getString(3);            // Get the table's catalog and schema names (if any)
            String tableCatalog = resultSet.getString(1);
            String tableSchema = resultSet.getString(2);
//                log.debug(String.format("catalog : %s, schema : %s",tableCatalog,tableSchema));
            dbInfo.addTable(tableName);
        }        Collections.sort(dbInfo.getTables(), new Comparator<String>() {
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
    }
我调用retreiveAllTables(String projPath, int maxThread)方法来检索当前工程所有数据库的所有表,工程中有262个数据库,有的库表达到1000多个表,有oracle,mysql,ms sqlserver三种数据库,现在的问题是,如果传递的;maxthread为5的话,只检索了8、9个库之后,线程就退出了,并没有继续执行,如果我传递大于262的值比如300,则所有的线程都执行完才退出。真是百思不得其解。

解决方案 »

  1.   

     DBInfo dbInfo = queue.poll();
                                if (dbInfo == null) {
                                    return null;
                                } else {
                                    log.debug("thread fetching table: "+Thread.currentThread().getName()+", "+dbInfo.getName());
                                    retreiveTables(dbInfo); //retreive all table names from the database of the dbinfo
                                }
    你确定dbInfo 不会为null吗?
      

  2.   

    最大的怀疑是出现了异常,检查过确实没有异常日志么?
    另外考虑把:
     public Object call()
    函数中直接套上个大的try{}catch(Exceptio ex),记得输出异常。
    另外在:
     DBInfo dbInfo = queue.poll();
    后面直接增加一句:
    System.out.println(dbInfo);看看poll了多少次内容,是否跟queue的大小一致。
      

  3.   


    嗯,确实是出异常了,try罩在call的整个方法体后,出现了java.sql.SQLException: The XAEMULATION connection property is invalid的异常,当线程数设得比较小,如3时会出现,是jtds的sql server驱动抛出的,如果设得比较大,则不会有问题
      

  4.   

    线程数设得大,只是偶尔出现问题。
    目前用的jtds是最新的1.2.5,过段时间有时间了,再试试微软的驱动。