web-dev-qa-db-ja.com

Java)にオブジェクトプールの最新の実装が見つかりません

Javaでのオブジェクトプールの最新の実装を探しています。 Apache Commonsのものを見ることができますが、正直なところ、ジェネリックスと、より新しいバージョンのJavaの並行性のものを使用するものが欲しいです。

コモンズプールは本当にうまく機能していますか?コードはきれいに見えます、えーと、醜いです。

カスタムの活性検証などを可能にするものが必要です。

ありがとう!

37
time4tea

Apache Commonsのものを見ることができますが、正直なところ、ジェネリックスと、より新しいバージョンのJavaの並行性のものを使用するものが欲しいです。

実は、この種のプロジェクト(汎用オブジェクトプール)は、最近は必要性がほとんどないため(オブジェクトの作成が安価であるため)、あまり注目されていません。これはおそらくあなたがそれらの多くを見ていない理由を説明しています(そして実際、私はコモンズプールしか知りません)。

そうは言っても、ジェネリックスが主な関心事である場合は、Commons Poolにパッチを適用できます。 POOL-8 を参照してください。パッチが添付されています。

コモンズプールは本当にうまく機能していますか?コードはきれいに見えます、えーと、醜いです。

いくつかあります 既知のバグ (4)ですが、私の知る限り、動作します。そして最後の文に関しては、まあ、あなたがもっと良いものを書くことができると思うなら、そしてあなたがそのための時間があるなら、なぜそれをやらないのですか?

カスタムの活性検証などを可能にするものが必要です。

選択肢は無限にありません。どちらか

  1. あなたが必要とするすべてを行う何かを見つけてください(私はそのようなライブラリを知りません、それは何もないという意味ではありません)。
  2. 箱から出して必要なすべてを実行するものが見つからない場合は、既存のソリューションを拡張します。
  3. あなた自身の解決策を転がしてください。
18
Pascal Thivent

Commons Poolは、プロジェクトに適した候補です。

  1. ジェネリックスインターフェース-コモンズプールの最も明白な問題は、そのプレジェネリックスインターフェースです。これを回避する方法はいくつかあります。あなたはできる
    1. キャスティングを行います。
    2. キャストを行うパラレルインターフェースを実装します。または
    3. パスカルが特定した パッチ を使用する
  2. 最近のJavaの並行性のもの-これは、気にしない実装の詳細です。並行性が正しければ、どのように正確さが達成されたかは問題ではありません。あるいは、より新しいものを使用しているが並行性が間違っているプールの実装は、依然として不十分な候補です。
  3. 醜いコード-結婚するのではなく、使うことになっています。
  4. カスタム活性検証validateObject を実装して、オブジェクトの活性をテストします。死んだオブジェクトは破壊されます。 Cron タスクを実装して、オブジェクトを定期的に借用および返却することもできます。これにより、デッドオブジェクトをタイムリーに削除できます。
8
emory

必要な機能を知らずに推奨を行うことは困難です。

プール内のオブジェクトの数が固定されている場合は、@ codedevourが言及した質問の この例 のようにBlockingQueueを使用できます。

プールする値をキーに関連付けることができる場合は、 MapMaker from Guava を使用できます。

ConcurrentMap<Key, Connection> connections = new MapMaker()
       .concurrencyLevel(32)
       .softKeys()
       .weakValues()
       .expiration(30, TimeUnit.MINUTES)
       .evictionListener(
           new MapEvictionListener<Key, Connection>() {
             public onEviction(Key key, Connection connection) {
               connection.close();
             } 
           });
       .makeComputingMap(
           new Function<Key, Connection>() {
             public Connection apply(Key key) {
               return createConnection(key);
             }
           });
7
NamshubWriter

KBOPをチェックアウトします。これは、単一のキーを単一のオブジェクトに、または単一のキーを複数のオブジェクトプールにブロックするスレッドセーフです。軽量で、依存関係を追加しません。

http://www.kbop.org

3
Jeremy Unruh

さらに別のプール( yapool )には、リスナーを介してプールイベントに作用するオプションを備えた汎用プール実装が含まれています( )。これにより、プールの動作のカスタマイズ、関数の追加、およびプールリソースの使用状況の診断に多くの柔軟性がもたらされます。または、プールの実装を拡張して、独自の目的の動作を追加することもできます( )。プールの実装はすでに相互に拡張されているため、これは比較的簡単です([基本]-> [バインド]-> [プルーニング])。

まず、単純な BoundPool を使用して独自のファクトリを設定するか(たとえば、前述のプールイベントの例の「LongFactory」を参照)、または単に ObjectPool を使用します。 。

Yapoolには「同期された」ブロックがなく、かなり高速です。

2
vanOekel

これはあなたの質問に関連しているようです、多分あなたは本当にあなた自身でオブジェクトプールを書くことを考えるべきです。 この基本的なJavaオブジェクトプールは機能しますか?

プーリングは当初、特にオブジェクトの作成とガベージコレクションのパフォーマンスが遅いためのチューニングアクションとして導入されました。最新のJVMでは、1.4を超えると、一般的なビジネスアプリケーションのメモリ管理を最適化するためにプーリングは不要になります。ガベージコレクタのパフォーマンスに悪影響を与えることさえあります。すべてのメソッド呼び出しで数百万のインスタンスを作成するなどの特別な場合でも、それでも効果があります。

ただし、インスタンスプーリングは、カスタムの「構築後」が遅いオブジェクトにとっては依然として興味深いものです。場合によっては、オブジェクトの作成後に依存関係を挿入したり、構成を読み取ったりする必要があります。これは時間がかかる可能性があり、何度も実行する必要はありません。このような場合、オブジェクトプーリングによって全体的なパフォーマンスが向上します。

Adam Bien -- オブジェクトプーリングはまだ役立つ可能性があります-まったく異なる理由で

コモンズプールフレームワークの強化についてどう思いますか?リファクタリングを行って汎用部分を追加することもできますが、他の人にとってもいいでしょう。

2

http://code.google.com/p/spf4j/ にオブジェクトプールの実装があります。Apachecommonsの実装よりも優れた実装だと思います。コードはそれほど醜くはなく、パフォーマンスも向上しています...

1
user2176913

ジェネリック側では、非ジェネリックライブラリを使用して、キャストを処理する非ジェネリックライブラリにアクセスするために使用するラッパーを作成してみませんか?そうすれば、キャストが行われる場所が1つになり、少なくともコードが少しクリーンアップされます。

0
jamiebarrow