隨筆-57  評論-202  文章-17  trackbacks-0
                使用Jakarta Commons Pool可以根據需要快速的實現自己的對象池,只需要實現PoolableObjectFactory或者KeyedPoolableObjectFactory接口。KeyedPoolableObjectFactory和PoolableObjectFactory的不同之處在于KeyedPoolableObjectFactory的每個方法都比PoolableObjectFactory多了一個Object key的參數,使用這個參數可以使得對象池中的每個對象都有所不同。
                PoolableObjectFactory定義了五個方法(摘至Jakarta Commons Pool API文檔):
          1. makeObject is called whenever a new instance is needed.
          2. activateObject is invoked on every instance before it is returned from the pool.
          3. passivateObject is invoked on every instance when it is returned to the pool.
          4. destroyObject is invoked on every instance when it is being "dropped" from the pool (whether due to the response from validateObject, or for reasons specific to the pool implementation.)
          5. validateObject is invoked in an implementation-specific fashion to determine if an instance is still valid to be returned by the pool. It will only be invoked on an "activated" instance. 


                下面是我的一個SocketChannel對象池的實現,實現了KeyedPoolableObjectFactory接口。

          package sample.pool;

          import java.net.SocketAddress;
          import java.nio.channels.SocketChannel;

          import org.apache.commons.pool.KeyedPoolableObjectFactory;

          /**
           * <p>Title: </p>
           *
           * <p>Description: </p>
           *
           * <p>Copyright: Copyright (c) 2005</p>
           *
           * <p>Company: </p>
           *
           * @author George Hill
           * @version 1.0
           
          */


          public class SocketPoolableObjectFactory implements KeyedPoolableObjectFactory {

              
          /**
               * 創建新的對象
               * @param key Object 創建對象需要用到的參數
               * @return Object SocketChannel實例
               * @throws Exception
               
          */

              
          public Object makeObject(Object key) throws Exception {
              SocketAddress address 
          = (SocketAddress) key;

              
          // 創建SocketChannel
              SocketChannel channel = SocketChannel.open(address);

              
          return channel;
            }


            
          /**
             * 銷毀對象
             * @param key Object 創建對象時的參數
             * @param obj Object 需要銷毀的對象
             * @throws Exception
             
          */

            
          public void destroyObject(Object key, Object obj) throws Exception {
              SocketChannel channel 
          = (SocketChannel) obj;

              
          if (channel != null)
                channel.close();
              channel 
          = null;
            }


            
          /**
             * 檢驗對象是否有效
             * @param key Object 創建對象時的參數
             * @param obj Object 需要進行檢驗的對象
             * @return boolean 有效返回true,無效返回false
             
          */

            
          public boolean validateObject(Object key, Object obj) {
              SocketChannel channel 
          = (SocketChannel) obj;

              
          if (channel != null && channel.isOpen() && channel.isConnected())
                
          return true;

              
          return false;
            }


            
          /**
             * 將對象激活,這里不需要做任何工作
             * @param key Object
             * @param obj Object
             * @throws Exception
             
          */

            
          public void activateObject(Object key, Object obj) throws Exception {
            }


            
          /**
             * 將對象掛起,這里不需要做任何工作
             * @param key Object
             * @param obj Object
             * @throws Exception
             
          */

            
          public void passivateObject(Object key, Object obj) throws Exception {
            }


          }

                我的測試程序:

          package sample.pool;

          import java.io.IOException;
          import java.net.
          *;
          import java.nio.ByteBuffer;
          import java.nio.channels.
          *;
          import java.util.
          *;

          import org.apache.commons.pool.
          *;
          import org.apache.commons.pool.impl.
          *;

          /**
           * <p>Title: 測試的線程類</p>
           *
           * <p>Description: </p>
           *
           * <p>Copyright: Copyright (c) 2005</p>
           *
           * <p>Company: </p>
           *
           * @author George Hill
           * @version 1.0
           
          */


          public class TestThread implements Runnable {

            
          // 線程名稱
            private String name;

            
          // 對象池
            private KeyedObjectPool pool;

            
          // 連接的網絡地址
            private InetSocketAddress address;

            
          public TestThread(String name, KeyedObjectPool pool,
                              InetSocketAddress address) 
          {
              
          this.name = name;
              
          this.pool = pool;
              
          this.address = address;
            }


            
          public void run() {
              System.
          out.println(name + ": Client Start");
              SocketChannel channel 
          = null;

              
          try {
                channel 
          = (SocketChannel) pool.borrowObject(address);
              }

              
          catch (Exception ex) {
                ex.printStackTrace();
              }


              
          // 從對象池中借出對象成功
              if (channel != null{
                System.
          out.println(name + ": Borrow Channel successfully!");

                
          try {
                  channel.configureBlocking(
          false);

                  
          // 創建Selector
                  Selector selector = Selector.open();
                  
          // 向Selector注冊我們需要的READ事件
                  SelectionKey skey = channel.register(selector, SelectionKey.OP_READ);

                  boolean stop 
          = false;
                  
          int n = 0;
                  
          int read = 0;
                  ByteBuffer buffer 
          = ByteBuffer.allocate(1024);

                  System.
          out.println("Client Start");

                  
          // 輪詢
                  while (!stop) {
                    
          // 獲取Selector返回的時間值
                    n = selector.select();

                    
          // 當傳回的值大于0事,讀事件發生了
                    if (n > 0{
                      Set 
          set = selector.selectedKeys();
                      Iterator it 
          = set.iterator();

                      
          while (it.hasNext()) {
                        skey 
          = (SelectionKey) it.next();
                        it.remove();

                        
          if (skey.isReadable()) {
                          SocketChannel sc 
          = (SocketChannel) skey.channel();

                          
          while ( (read = sc.read(buffer)) != -1{
                            
          if (read == 0{
                              
          break;
                            }


                            buffer.flip();
                            
          byte[] array = new byte[read];
                            buffer.
          get(array);
                            String s 
          = new String(array);
                            System.
          out.print(s);
                            buffer.clear();

                            
          if (s.indexOf("new"!= -1{
                              stop 
          = true;
                              System.
          out.println();
                            }

                          }

                        }

                      }

                    }

                  }

                }

                
          catch (IOException ioe) {
                  ioe.printStackTrace();
                }


                
          try {
                  pool.returnObject(address, channel);
                }

                
          catch (Exception ex) {
                  ex.printStackTrace();
                }

              }


              System.
          out.println(name + ": Client Stop");
            }


            
          /**
             * 測試方法
             * @param args String[] 控制臺參數
             * @throws Exception
             
          */

            
          public static void main(String[] args) throws Exception {
              SocketPoolableObjectFactory factory 
          = new SocketPoolableObjectFactory();
              StackKeyedObjectPoolFactory poolFactory 
          = new StackKeyedObjectPoolFactory(factory);
              KeyedObjectPool pool 
          = poolFactory.createPool();

              
          // 創建連接清華BBS的線程
              Thread t1 = new Thread(new TestThread("清華", pool, new InetSocketAddress("bbs.tsinghua.edu.cn"23)));
              t1.start();
              
          // 創建連接華南理工BBS的線程
              Thread t2 = new Thread(new TestThread("華南理工", pool, new InetSocketAddress("bbs.gznet.edu.cn"23)));
              t2.start();
            }


          }



                參考資料:
                1. Jakarta Commons Pool網站:http://jakarta.apache.org/commons/pool/
                2. IBM開發者的一篇很好的文章《使用Jakarta Commons Pool處理對象池化》
          posted on 2005-05-20 14:08 小米 閱讀(4095) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 邹城市| 凯里市| 札达县| 嘉黎县| 浠水县| 江油市| 苗栗市| 孟连| 呼图壁县| 肇源县| 云霄县| 鹿泉市| 海晏县| 章丘市| 社会| 汉源县| 舒城县| 平陆县| 罗江县| 松原市| 英山县| 鄂温| 天等县| 古浪县| 顺昌县| 临沭县| 牟定县| 阿拉善盟| 德令哈市| 内丘县| 五寨县| 城步| 平谷区| 长春市| 苍南县| 望奎县| 南京市| 海城市| 灵寿县| 万山特区| 随州市|