使用Proxy.newProxyInstance包裝物件池,免去returnObject方法呼叫

stephen發表於2004-12-07

希望能實現一個物件池,但是同時要避免呼叫returnObject。

因為如果可以避免呼叫returnObject,那麼就原來的程式碼就可以不做修改就能使用物件池優化功能了。

下面是為了實現上述功能寫的示例程式碼。

先宣告一點,準備儲存到池裡面的物件是不用在兩次呼叫之間儲存狀態的。

所以下面的示例程式碼中,每次呼叫一個方法的時候,都從池裡面找一個物件,用完之後,立即歸還。

所以原來的程式碼中,每次使用物件的時候,從工廠裡面new一個物件出來,使用完了也不做任何處理。

類似如下程式碼。

....
SamplePortType obj = new SampleClass();
obj.helloWorld();
....

<p>

另外,由於是示例程式碼,所以裡面涉及多執行緒同步的問題也做處理。

程式碼雖然寫了出來,就這個示例程式來說,也能跑了,

但是對其中的實現方法存在一些疑問。

主要的疑問是,示例程式碼中,Proxy.newProxyInstance 每次都是使用同樣的一個物件來建立動態代理,

然後實際invoke(Object proxy, Method method, Object[] args)的時候,使用另外一個物件去執行。

不知道這樣做會不會存在問題?

不知道為了實現剛開始提出的問題,有什麼其他辦法?

import java.util.logging.*;
import java.util.Stack;
import java.lang.reflect.*;
import java.lang.Object;
import java.lang.System;

interface SamplePortType {
  public void helloWorld ( );
};

class SampleClass implements SamplePortType {
  public SampleClass ( ) { }
  public void helloWorld ( ) {
    System.out.println ( "Hello world!" );
  }
};

class SamplePool {
  static private SamplePool _instance;
  static public SamplePool getInstance() {
    if ( null == _instance ) {
      _instance = new SamplePool();
    }
    return _instance;
  }

  private SamplePool ( ) { _pool = new Stack(); }

  public SamplePortType borrowObject ( ) {
    if ( _pool.empty() ) {
      return new SampleClass();
    } else {
      return (SamplePortType)_pool.pop();
    }
  }

  public void returnObject ( SamplePortType obj ) { _pool.push ( obj ); }

  private Stack _pool;
};

public class AOPHandler implements InvocationHandler {
  static private SamplePortType _orgObject = null;

  public static SamplePortType getObject ( ) {
    if ( null == _orgObject ) _orgObject = new SampleClass();
    return (SamplePortType)Proxy.newProxyInstance(
        _orgObject.getClass().getClassLoader(),
        _orgObject.getClass().getInterfaces(),
        new AOPHandler() );
  }

  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {

    SamplePortType obj = SamplePool.getInstance().borrowObject();
    Object result = null;
    result = method.invoke(obj, args);
    SamplePool.getInstance().returnObject ( obj );
    return result;
  }

  static public void main ( String args[] ) {
    SamplePortType obj = AOPHandler.getObject();
    obj.helloWorld ( );
  }
}

<p>

相關文章