粗略的架子 具体的实现在继承线程的抽象类的类中做 我前段时间需要用写的 未必很严密线程池:import java.util.LinkedList;public abstract class Manager {    private String mThreadPoolName = null;    private int mThreadPoolMaxSize = 1;    private LinkedList workers = new LinkedList();    public Manager() {
    }    public Manager(String name, int poolMaxSize) {
        mThreadPoolName = name;
        createWorker(name, poolMaxSize);
        mThreadPoolMaxSize = poolMaxSize;
    }    private void createWorker(int poolMaxSize) {
            for (int i = 0; i < poolMaxSize; i++) {
                Worker worker = new ...Worker(this);
                workers.addLast(worker);
            }
    }    public synchronized Worker getIdleWorker() {
        return (Worker)workers.removeFirst();
    }    public synchronized void notifyFree(Worker worker) {
        if (workers.size() < mThreadPoolMaxSize) {
            workers.addLast(worker);
        } else {
            worker = null;
        }
    }    public int getThreadPoolMaxSize() {
        return mThreadPoolMaxSize;
    }    public void setThreadPoolMaxSize(int threadPoolMaxSize) {
        this.mThreadPoolMaxSize = threadPoolMaxSize;
    }}线程抽象类public abstract class Worker implements Runnable {    private Manager mManager = null;    private Thread mThread = null;
  
    public Worker() {
    }    public Worker(String threadName, Manager manager) {
        mManager = manager;
        mThread = new Thread(this, threadName);
        init();
        mThread.start();
    }    public abstract void init();    public void run() {
        while (true) {
            waitForStart();
            Worker worker = mManager.getIdleWorker();
            process();
            isRunning = false;
            mManager.notifyFree(worker);
        }
    }    public abstract void process();    public void start() {
        isRunning = true;
        mManager.getIdleWorker();
        notifyToStart();
    }    public synchronized void waitForStart() {
        try {
            wait();
        } catch (InterruptedException ex) {
        }
    }    public synchronized void notifyToStart() {
        notify();
    }}

解决方案 »

  1.   

    你的问题在google里面很多很多,100分浪费啊
      

  2.   

    连接就是指tcpip连接(数据库和网络编程都有用,主要是数据库要用),这个东东建立和挂断都很耗时,所以就有让它wait在哪里,下次直接用的方法。这就是连接池提高性能的原理。如果要tcpip连接wait在哪里,就要让使用socket的线程wait住,这就是为什么一定要用线程和线程同步方法编写连接池的原因。所以连接池有时也叫线程池。我就懂这么多了,线程同步编程很麻烦……因为要考虑线程安全等问题。现在对数据库的连接池,一般的应用服务器(比如tomcat和jboss等)都有提供,需要按照应用服务器各自的格式配置一个所谓数据源,到jndi里,之后要做数据库应用时只要获得这个数据源就可以享受连接池带来的好处了。
      

  3.   

    不同的应用服务器提供不同的连接池,但是大致设定方法都是一样的,
    调用也很简单,几句简单代码就可,不同应用服务提供商,提供不同的look up方式
    这些楼主可以根据需要了解。
      

  4.   

    tomcat里有dbcp,就提供了连接池的调用,只要配置一下就可以啦只要了解连接池是什么意思就够了,应该不需要自己去实现吧
      

  5.   

    import java.io.*;
    import java.sql.*;
    import java.util.*;
    import java.util.Date;
    public abstract class DBPoolManager {
      static protected int clients; //
      protected Vector drivers = new Vector();
      protected PrintWriter log;
      protected Hashtable pools = new Hashtable();
      protected Connection con;  /**
       * 将连接对象返回给由名字指定的连接池
       *
       * @param name 在属性文件中定义的连接池名字
       * @param con 连接对象
       */
      public void freeConnection(String name, Connection con) throws Exception {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        if (pool != null) {
          pool.freeConnection(con);
        }
        else {
          //throw new Exception("释放连接,没有找到对应名称的连接池对象,请确认名称是否正确:"+name+"!");
          //modified by czh 20050201
          throw new Exception(new StringBuffer(
              "freeconn,conn type name not found,name=").append(name).append("!").
                              toString());
        }
      }  /**
       * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
       * 限制,则创建并返回新连接
       *
       * @param name 在属性文件中定义的连接池名字
       * @return Connection 可用连接或null
       */
      public Connection getConnection(String name) throws Exception {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        Connection conn = null;
        try {
          if (pool != null) {
            conn = pool.getConnection();
          }
          else {
            //throw new Exception("连接池对象为空,请确认" + name + "的相关配置信息!");
            //modified by czh 20050201
            throw new Exception(new StringBuffer(
                "conn pool object is empty,please check the db configration of ").
                                append(name).toString());
          }
        }
        catch (Exception e) {
          e.printStackTrace(log);
          //throw new Exception("获取连接错误:" + e.getMessage());
          //modified by czh 20050201
          throw new Exception(new StringBuffer("get conn error:").append(e.
              getMessage()).toString());
        }
        return conn;
      }  /**
       * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
       * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
       *
       * @param name 连接池名字
       * @param time 以毫秒计的等待时间
       * @return Connection 可用连接或null
       */
      public Connection getConnection(String name, long time) throws Exception {
        DBConnectionPool pool = (DBConnectionPool) pools.get(name);
        Connection conn = null;
        try {
          if (pool != null) {
            conn = pool.getConnection(time);
          }
        }
        catch (Exception e) {
          throw new Exception(e.getMessage());
        }
        return conn;
      }  /**
       * 关闭所有连接,撤销驱动程序的注册
       */
      public synchronized void release() {
        // 等待直到最后一个客户程序调用
        if (--clients != 0) {
          return;
        }    Enumeration allPools = pools.elements();
        while (allPools.hasMoreElements()) {
          DBConnectionPool pool = (DBConnectionPool) allPools.nextElement();
          pool.release();
        }    Enumeration allDrivers = drivers.elements();
        while (allDrivers.hasMoreElements()) {
          Driver driver = (Driver) allDrivers.nextElement();
          try {
            DriverManager.deregisterDriver(driver);
            log("Unload JDBC Driver " + driver.getClass().getName());
          }
          catch (SQLException e) {
            log(e, "Unload JDBC Driver Failure: "
                + driver.getClass().getName());
          }
        }
      }  /**
       * 根据指定属性创建连接池实例.
       *
       * @param props 连接池属性
       */
      protected void createPools(Properties dbInfo) {
        if (dbInfo != null) {
          String poolName = dbInfo.getProperty("name");
          String poolDriver = dbInfo.getProperty("driver");
          String poolURL = dbInfo.getProperty("url");
          String poolUsername = dbInfo.getProperty("username");
          String poolPassword = dbInfo.getProperty("password");
          String logFile = dbInfo.getProperty("log");
          try {
            log = new PrintWriter(new FileWriter(logFile, true), true);
          }
          catch (IOException e) {
            System.err.println("can not open the log file: " + logFile);
            log = new PrintWriter(System.err);
          }
          int poolMaxConn = Integer.parseInt(dbInfo.getProperty("maxConn"));
          DBConnectionPool pool = new DBConnectionPool(poolName, poolDriver,
              poolURL, poolUsername, poolPassword, poolMaxConn);
          pools.put(poolName, pool);
          System.out.println(poolURL + poolUsername + poolDriver);
          log("Connection pool created success:" + poolName);
        }
        else {
          log("connection pool created failed,db property is empty!");
        }
      }  /**
       * 读取属性完成初始化
       */
      protected void init() {
        Properties dbInfo = new Properties();
        InputStream is = this.getClass().getResourceAsStream("dbInfo.properties");
        try {
          dbInfo.load(is);
        }
        catch (IOException ioe) {
          log("Read File Error");
        }
        loadDrivers(dbInfo);
        createPools(dbInfo);
      }  /**
       * 装载和注册所有JDBC驱动程序
       *
       * @param props 属性
       */
      protected void loadDrivers(Properties dbInfo) {
        if (dbInfo != null) {
          try {
            Driver driver = (Driver) Class.forName(dbInfo.getProperty("driver")).
                newInstance();
            DriverManager.registerDriver(driver);
            drivers.addElement(driver);
            log("Register JDBC  Driver success! " + dbInfo.getProperty("driver"));
          }
          catch (Exception e) {
            log("Cannt Register JDBC Driver: " + dbInfo.getProperty("driver") + ", Eroor Info: " +
                e.getMessage());
          }
        }
        else {
          log("Cannt Register JDBC Driver: DB property is emperty!");
        }
      }  /**
       * 将文本信息写入日志文件
       */
      protected void log(String msg) {
        System.out.println(new Date() + ": " + msg);
      }  /**
       * 将文本信息与异常写入日志文件
       */
      protected void log(Throwable e, String msg) {
        log.println(new Date() + ": " + msg);
        e.printStackTrace(log);
      }  /****************************************************************/
      /**********************内部类DBConnectionPool*********************/
      /****************************************************************/
      /**
       * 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
       * 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
       */
      class DBConnectionPool {    private int checkedOut; //当前连接数
        private Vector freeConnections = new Vector(); //保存所有可用连接
        private String driver; //连接池DRIVER
        private int maxConn; //此连接池允许建立的最大连接数
        private String name; //连接池名字
        private String password; //密码或null
        private String URL; //数据库的JDBC URL
        private String user; //数据库账号或null    /**
         * 创建新的连接池
         *
         * @param name 连接池名字
         * @param URL 数据库的JDBC URL
         * @param user 数据库帐号或 null
         * @param password 密码或 null
         * @param maxConn 此连接池允许建立的最大连接数
         */
        public DBConnectionPool(String name, String driver, String URL, String user,
                                String
                                password, int maxConn) {      this.name = name;
          this.driver = driver;
          this.URL = URL;
          this.user = user;
          this.password = password;
          this.maxConn = maxConn;    }
      

  6.   

    /**
         * 将不再使用的连接返回给连接池
         * @param con 客户程序释放的连接
         */
        public synchronized void freeConnection(Connection con) {
          //将指定连接加入到向量末尾
          //是否要判断con=null或Closed的状态?? czh 2004/8/8
          try {
            // System.out.println("空闲连接数目," + freeConnections.size());
            if (con == null || con.isClosed()) {
              try {
                throw new Exception(
                    "ERROR:returned a null or closed connection,connection may be leaked,check your program!");
              }
              catch (Exception e) {
                e.printStackTrace();
              }
              checkedOut--;
              return;
            }
            freeConnections.addElement(con);
            checkedOut--;
            System.out.println(new StringBuffer(
                "1 returned,frees:").append(
                freeConnections.size()).toString());
            /*****这里是干什么 ?***/
            if (freeConnections.size() > maxConn) { //modify by huangqiao 2004/8/2 question: notifyAll()???
              notifyAll(); //删除等待队列中的所有线程
              con = null;
              this.getConnection();
            }
            /*****这里是干什么 ?***/
          }
          catch (Exception e) {
            e.printStackTrace();
          }
          notifyAll(); //唤醒等待队列中的所有线程
        }    /**
         * 从连接池获得一个可用连接.如果没有空闲的连接且当前连接数小于最大连接
         * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
         * 然后递归调用自己以尝试新的可用连接.
         */
        public synchronized Connection getConnection() throws Exception {
          Connection con = null;
          //System.out.println("freeConnections.size():"+freeConnections.size());
          if (freeConnections.size() > 0) {
            //System.out.println("进入了freeConnections.size() > 0");
            // 获取向量中第一个可用连接
            try {
              con = (Connection) freeConnections.firstElement();
              freeConnections.removeElementAt(0);
              //System.out.println("进入了freeConnections.size() > 0 con"+con);
              if (con == null || con.isClosed()) {
                log(new StringBuffer(
                    "removed a valid(null or closed) connection from pool ").append(
                    name).toString());
                // 递归调用自己,尝试再次获取可用连接
                con = getConnection();
              }
            }
            catch (SQLException e) {
              log("get conn err:" + e.getMessage());
              // 递归调用自己,尝试再次获取可用连接
              con = getConnection();
            }
          }
          else if (maxConn == 0 || checkedOut < maxConn) {
            try {
              con = newConnection();
            }
            catch (Exception e) {
              throw new Exception(e.getMessage());
            }
          }
          else {
            String errs = new StringBuffer("connections number returned to Maximum,Maximum is ").
                append(maxConn).append(",checkedouted:").append(checkedOut).
                toString();
            System.out.println(errs);
            log(errs);
            throw new Exception(errs);
          }
          if (con != null) {
            checkedOut++;
          }
          return con;
        }    /**
         * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
         * 参见前一个getConnection()方法.
         * @param timeout 以毫秒计的等待时间限制
         */
        public synchronized Connection getConnection(long timeout) throws Exception {
          long startTime = new Date().getTime();
          Connection con = null;
          while ( (con = getConnection()) == null) {
            try {
              wait(timeout);
            }
            catch (InterruptedException e) {}
            if ( (new Date().getTime() - startTime) >= timeout) {
              // wait()返回的原因是超时
              //return null;
              throw new Exception(
                  "get conn time out,may be conn numbers been MAXIMUM!");
            }
          }
          return con;
        }    /* 关闭所有连接*/
        public synchronized void release() {
          Enumeration allConnections = freeConnections.elements();
          while (allConnections.hasMoreElements()) {
            Connection con = (Connection) allConnections.nextElement();
            try {
              con.close();
              log("close a conn of pool " + name);
            }
            catch (SQLException e) {
              log(e, "can not close conn of pool:" + name);
            }
          }
          freeConnections.removeAllElements();
        }    /** 创建新的连接**/
        private Connection newConnection() throws Exception {
          Connection conn = null;
          try {
            System.out.println(driver);
            Class.forName(driver);
          }
          catch (ClassNotFoundException e) {
            System.out.println("Class Error");
          }
          try {
            conn = DriverManager.getConnection(URL, user, password);
            log(new StringBuffer("connection pool created a new conn:").append(name).
                toString());
          }
          catch (SQLException e) {
            System.out.println(new StringBuffer(
                "create  new conn failure!connection URL:").append(
                URL).append(",UID:").append(user));
            log(e, "create  new conn failure: " + URL);
          }
          return conn;
        }
      }}
      

  7.   

    这年头谁还老土自己写啊,用得着吗?基本上每个appserver都提供了自己的连接池,只要配置一下web应用服务器的连接池就行了。如果你跟我讲你用的web服务器没有提供连接池,那我跟你说,你用的那个还叫web服务器么,呵呵。或者是你也可以参考成熟的连接池作品c3p0,proxool,dbcp来使用,比你自己写的绝对强一百倍。不过不推荐你用dbcp,什么原因,网上太多的文章了,自己搜索一下就知道了。
      

  8.   

    既然appserver里自带了连接池自己再配一下写很少的代码来调用就行了? 
    那为什么来了几个DBConnectionpool.java都是很长的啊?这是自己实现的还是也是调用服务器自带的?请指教~
      

  9.   

    既然appserver里自带了连接池自己再配一下写很少的代码来调用就行了? 
    那为什么来了几个DBConnectionpool.java都是很长的啊?这是自己实现的还是也是调用服务器自带的?请指教~
      

  10.   

    小伙子不要急躁,慢慢来,现在的服务器都带有数据库连接池,线程池等功能,你按服务器的配置说明配置一下,非常容易的,在程序中用jndi获取datasource,从而取得连接。
      

  11.   

    上面的DBConnectionpool.java那些代码是自己实现的。实际上我觉得没啥大用,自己写的哪有服务器自身提供的好啊,毕竟是服务器自己的提供的连接池。
      

  12.   

    连接池是跟具体的servlet容器配搭在一起的,连接池的布置跟配置都是在servlet容器的上面进行配置。只要一切都好了,调用就行了,不用理会连接池后台的工作,serlvet容器会为你搞掂。