繁体   English   中英

如何从Java中的多个线程获取和处理对象? 如何创建Future的多个实例

[英]How to take and handle object from multiple threads in Java? How to create Multiple instances of Future

我需要创建一堆到不同主机的JMX连接。 我正在尝试并行创建这些连接。 在这方面表现要好得多。

我的方法是我传递“主机和端口”条目的集合。 对于每个条目,将创建一个连接。

现在我正在提交创建多线程连接的任务。 但我不知道如何获取返回并存储线程创建的连接对象。

代码是这样的,

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.

}

看一下ThreadPool的invokeAll方法 - 它需要一组Callables并返回一个Futures列表。

编辑:使用invokeAll而不是简单地一次提交一个任务并将Futures放在你自己的列表中的优点是invokeAll只会在所有任务完成后返回,所以你不必继续检查所有的Futures看他们是否已经完成。

一旦每个线程(您的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 ...等等。 希望有所帮助。

根据这个 javadoc, Future<V>.get()方法,它返回一个V类型的对象。 您应该调用该方法来接收Future执行的结果。 从被调用者线程调用它是安全的。

您可以使用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()调用必须在另一个循环中完成,否则你将阻塞你的线程直到刚刚提交的callable完成。 所以:

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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM