1

さまざまなホストへの一連の JMX 接続を作成する必要があります。これらの接続を並行して作成しようとしています。このパフォーマンスでは、今でははるかに優れています。

「ホストとポート」エントリのコレクションを渡すメソッドがあります。エントリごとに 1 つの接続が作成されます。

現在、複数のスレッドへの接続を作成するこのタスクを提出しています。しかし、スレッドによって作成された接続オブジェクトを取得して保存する方法がわかりません。

コードは次のようになります。

ConnectionFactory.createConnections(collection of hostportEntries)

class ConnectionFactory{

public static CollectionOfConnections createConnections(ListOfHostPorts)
{

   ExecutorService exec = Executors.newFixedThreadPool(4);

   for(iterate over hostportEntries)
   {
     Future<Connection> future1 = exec.submit(new connCreator(HostPortEntry));

      //Now here, connCreator is implementing Callable Interface and creating connection. and returning it. I'm taking reference of that Returned connection. 
//But how will I take              Multiple Connection objects returned by Multiple threads. I tried to create Future[] but OPTION like that doesn't seem to be there
      // Can anybody help here?????

   }

//if I succeed in getting the objects return then I'll store in one more collection and return those for further use of those connections.

}
4

4 に答える 4

2

ThreadPool の invokeAll メソッドを見てください。Callable のコレクションを受け取り、Future のリストを返します。

編集: 単純にタスクを 1 つずつ送信して Future を独自のリストに入れるよりも invokeAll を使用する利点は、すべてのタスクが完了した後にのみ invokeAll が返されるため、すべての Future をチェックし続ける必要がないことです。完了したかどうかを確認します。

于 2013-01-10T19:16:04.283 に答える
1

各スレッド(ConnectionCreator)が接続を作成したら、ある種のシングルトンを使用して、新しく作成された接続へのハンドルを登録する必要があります。EJBコンテナ内で実行している場合、これはセッションBeanを使用して簡単に実行できます。基本的に、このセッションBeanは「接続プール」になる可能性があります。接続作成者内で、次のことを実行できます(簡潔にするために、例外処理や、すでに実行する必要のあるその他の処理は除外しています)。

Inside of ConnectionCreator
============================

// Create your connection
Connection myConnection = doWhateverToCreateConnection();

// Presuming things went fine, get a handle to the session bean.  You could
// also potentially do this through resource injection using Spring or what not.  
Context ctx = new InitialContext();
ConnectionPoolBean connectionPoolBean = ( ConnectionPoolBean )ctx.lookup( "java:module/ConnectionPoolBean" );

// Now, register the connection with the pool
connectionPoolBean.registerConnection( myConnection );

次に、ConnectionPoolBeanで、接続オブジェクトのコレクションを保持します。これらのオブジェクトには、登録メソッドと登録解除メソッド、および可能なgetConnection...などが必要です。お役に立てば幸いです。

于 2013-01-10T19:19:31.447 に答える
0

これによると、 javadocFuture<V>には。.get()タイプのオブジェクトを返すメソッドがありますVFuture実行結果を受け取るには、そのメソッドを呼び出す必要があります。呼び出し先スレッドから呼び出すのは安全です。

于 2013-01-10T19:21:19.533 に答える
0

ExecutorCompletionServiceを使用して接続オープナーを実行し、最初に接続を開いた人の順に取得できます:)

したがって、あなたのコードでは、次のようになります

ExecutorService exec = Executors.newFixedThreadPool(4);
CompletionService<Result> ecs
       = new ExecutorCompletionService<Result>(exec);

for (HostPortEntry hpe : hostportEntries) { ecs.submit(new ConnCreator(hpe)); }

Collection<Connection> connections = new ArrayList<Connection>(hostportEntries.size());
for (int i = 0; i < hostportEntries.size(); i++) {
    // will add the created connections in order of what finish first.
    connections.add(ecs.take().get());
}
return connections;

お役に立てれば :)

編集

重要: CompletionService とExecutor#submit. 問題は、への呼び出しを別のループで実行するFuture#get() 必要があることです。そうしないと、送信された呼び出し可能オブジェクトが終了するまでスレッドをブロックします。そう:

Collection<Future> connCreatorsFuture = new ArrayList<Future<Connection>>(hostportEntries.size());
for (HostPortEntry hpe : hostportEntries) { connCreatorsFuture.add(exec.submit(new ConnCreator(hpe))); }

Collection<Connection> connections = new ArrayList<Connection>(hostportEntries.size());
for (Future<Connection> connection : connCreatorsFuture) {
    // will wait until this connCreator finishes.
    connections.add(connection.get());
}
return connections;
于 2013-01-10T20:15:15.700 に答える