这是我的问题:
我有一大堆相同的对象。这些对象与服务器连接。从服务器获取数据需要4或5秒,因为服务器很慢。
现在我需要所有对象来获取数据。所以我为每个对象调用MyObject.getData()。我可以在一系列中完成,但是20个物体,每个花费5秒钟太慢了。我以为我应该使用线程并将每个对象放在自己的线程上。
这是我的问题:
如果我让对象扩展线程。将调用o MyObject.getData();在该对象的线程中运行,或者在调用该方法的线程中运行?我知道我可以使用Thread.Run()来获取对象,但这不是我想要的。我想让方法按照我的意愿运行。
那我该怎么做?
非常感谢。
答案 0 :(得分:2)
教科书的方法可能是这样的:
class GetDataObj implements Callable<Data> {
public Data call(){
//get data
return data;
}
}
然后
ExecutorService exec = Executors.newCachedThreadPool();
Set<Callable<Data>> objects = //get objects;
List<Future<Data>> futures = exec.invokeAll(objects);
for(Future<Data>> future : futures){
Data data = future.get();
//do stuff with data
}
exec.shutdown();
请注意,当您遍历futures
时,get()
方法将会阻止,直到结果可用于DataObj
。如果你想等到所有数据都可用,这很好。
答案 1 :(得分:1)
如果调用object.myMethod(),该方法将在调用者线程中运行。
你必须启动()线程才能使它运行,而不是调用run()方法。
您可以这样做,重写您的对象,以便myMethod()方法启动一个新线程。因此,您可以使用与实际完全相同的对象。但是如果myMethod返回了一些内容,那就是那个更改,因为你必须等待线程终止befor
答案 2 :(得分:1)
我认为最好使用线程池从对象中获取数据。因此,您需要每个对象来实现Runnable。请参阅thread pools。
如果在获得数据后将对队列的引用传递给对象,则可以将它们放入队列中。然后,主线程可以在准备好时将数据从队列中取出。 请参阅producer-consumer pattern。
这方面的一个例子是:
BlockingQueue<Data> queue = new BlockingQueue<Data>();
ExecutorService pool = Executors.newFixedThreadPool(5);
//implements Runnable, getting data from this
//places Data object in queue instead of returning it
DataObject obj = new DataObject(queue);
pool.execute(obj); //invokes the run method of the DataObject
Data data = queue.take();
您需要为多个对象设置for循环。
希望这有帮助。