多線程調用AXIS2 線程不安全客戶端stub 解決辦法:對象池

網上關於多線程調用webService全是一句話:”雖然直接使用多線程可以很好地解決這個問題,但比較麻煩。幸好Axis2的客戶端提供了異步訪問WebService的功能。 ”
我也知道比較麻煩,也知道幸好Axis2的客戶端提供了異步訪問WebService的功能。但是能別每篇文章都是一樣的轉載嗎?我踏馬就是想知道直接使用多線程調用webService的資料!

網上關於多線程調用axis2生成的stub,能否採用單例,全無資料.
求人不如求己,翻遍中文資料,英文文檔得出以下結論及解決辦法:

axis2生成客戶端線程不安全,多線程調用webService時有兩種解決辦法:
1.每個線程新new一個stub對象
2.stub單例

這兩種方法皆不可行,原因如下:
1方法不可行,因爲stub爲重量級對象,可類比JDBC Connection,創建大量消耗資源.
2方法不可行,因爲stub線程不安全,不可多線程操作同一實例.

針對如上問題可採用對象池方法解決,在對象池初始化一部分對象,每個線程從對象池中取出所需要的stub實例,互不干擾.

對象池代碼如下,需要stub實例時,從該對象池中取:

public final class StubFactory extends BasePooledObjectFactory<Stub> {

    static GenericObjectPool<Stub> pool = null;

    // 取得對象池實例
    public synchronized static GenericObjectPool<Stub> getPoolInstance() {
        if (pool == null) {
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            poolConfig.setMaxTotal(SystemMessage.getInt("pool.max.total"));
            poolConfig.setMaxIdle(SystemMessage.getInt("pool.max.idle"));
            poolConfig.setMinIdle(SystemMessage.getInt("pool.min.idle"));
            poolConfig.setMaxWaitMillis(SystemMessage.getLong("pool.max.wait.millis"));
            poolConfig.setTestOnBorrow(SystemMessage.getBoolean("pool.test.on.borrow"));
            pool = new GenericObjectPool<Stub>(new StubFactory(), poolConfig);
        }
        return pool;
    }

    public static Stub borrowObject() throws Exception{
        return (Stub) StubFactory.getPoolInstance().borrowObject();
    }

    public static void returnObject(Stub stub) throws Exception{
        StubFactory.getPoolInstance().returnObject(stub);
    }

    public static void close() throws Exception{
        StubFactory.getPoolInstance().close();
    }

    @Override
    public Stub create() throws Exception {
        return new Stub(SystemMessage.getString("crm_url_async"));
    }

    @Override
    public PooledObject<Stub> wrap(Stub obj) {
        return new DefaultPooledObject<Stub>(obj);
    }

    public static void main(String[] args) {
        while(true) {
            try {
                Stub stub = StubFactory.getPoolInstance().borrowObject();
                System.out.println(stub.hashCode());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

附上對象池配置參數:


pool.max.total=15
pool.max.idle=10
pool.min.idle=5
pool.max.wait.millis=5000
pool.test.on.borrow=false

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章