1

インターフェイスFooClientImplを実装するサードパーティの Java クラスを使用しています。FooClient

interface FooClient {
    public FooOutput processFoo(FooInput inputData);
}

localhostこれは、特定のポート番号の TCP ソケットを介してサードパーティの非 Javaプロセスと通信することにより、渡されたデータを処理しfooserverます。各inputDataインスタンスはスタンドアロンで処理できます (つまり、驚くほど並列です)。fooserverかなり遅いですが、単一のコアで実行されるだけなので、複数のインスタンスを個別のポートで手動で起動し、複数のFooClientImplインスタンスにアクセスできるようにしたいと思います-サーバーインスタンスごとに1つ。ここまでは簡単です。

ConcurrentFooClientImplただし、インターフェイスも実装するクラスを作成したいと思いますが、内部では、インスタンスまたはサブクラス インスタンス (おそらく 8)FooClientのプールを追跡し、メソッドが実行された後、最初の未使用のインスタンスで着信データを処理します。呼び出されます (必要に応じて使用可能になるまで待機します)。そうすれば、他のコードをインスタンス化でき、呼び出し元のコードには同じように見えますが、より高速になります。FooClientImpl.processFoo()ConcurrentFooClientImpl

私はスレッド化に非常に慣れていないため、Java Concurrency チュートリアルを一通り見て回りましたが、この使用例はそこにある例とは多少異なるようです。

インスタンスをラップするサブクラスを作成する必要があると思います。また、固定サイズのクライアント プールを管理するためにも使用する必要があると思います。そして、それらをプールに送信するために、何らかの方法で の実装にラップすることができました。しかし、これらのインスタンスは特定のインスタンスを取得する必要があるため、適切なポートで実行されているインスタンスを呼び出して実際に通信することができます。彼らは結果を呼び出してキャストできると思いますThreadFooClientImplThreadFooClientImplExecutors.newFixedThreadPoolThreadFactoryFooClientImplThreadConcurrentFooClientImpl.processFoo()inputDataCallableFooClientFooClientImplThread.processFoo()fooserverThread.currentThread()FooClientImplThread. しかし、直感的にはハッキリと感じます (ただし、ここで私の直感を信頼するかどうかはわかりません)。

ここで考えられる解決策で正しい方向に進んでいますか、それとももっとまともなアプローチがありますか?

更新:説明されているようなソリューションを実装することになりました。驚いたことに、ほとんどが期待どおりに機能しましたが、もちろん、外向きの API を維持しながらバックグラウンド処理に何が必要になるかを考えていなかったことに気付きました。私が知る限り、これは、上で概説した一度に 1 つずつ呼び出し元によってトリガーされる API では不可能です。生産者と消費者のパターンか何かに置き換える必要があり、別の方法ではありますが、最終的にはそれを行いました。

4

1 に答える 1

2

あなたはこれを乱暴に調理しすぎています。必要なのは、サーバーの TCP 部分をマルチスレッド化することです。つまり、受け入れたソケットごとに新しいスレッドを開始します。次に、それらのスレッドがすべて同じ FooImpl オブジェクトを共有するか、またはそれぞれが独自のオブジェクトを 1 つ持つかのいずれかを、FooImpl の実装方法を考慮して意味のある方にします。新しいスレッド クラスは必要ありません。何もプールする必要はありません。注意: Java オブジェクトがシングル スレッドであることがわかっていない限り、Java オブジェクトは 1 つのコアでしか実行されないというのは正しくありません。

于 2013-01-08T07:39:21.720 に答える