0

Here's my problem:

I have a whole bunch of identical objects. These objects interface with a server. It takes 4 or 5 seconds to get data from the server, as the server is slow.

Now i need all the objects to get data. So i call MyObject.getData() for each object. I could do it in a series but 20 objects, each taking 5 seconds is too slow. I thought I should use threads and have each object on its own thread.

Here's my question:

If i make the objects extend thread. Will a call to o MyObject.getData(); run in that object's thread, or in the thread the method was called from? I know i can use Thread.Run() to get the object going but thats not what i want. I want to get methods running at my will.

So how do i do this?

Thanks so much.

2
  • 3
    Thread.run() will not "get the object going" -- that's a common misconception. What you'll want to invoke is Thread.start(). Commented Jun 21, 2011 at 22:16
  • Best practice is NOT to extend Thread. Rather, you should implement Runnable or Callable (like most of the answers suggest). Using these interfaces instead allows you to still start manual Thread objects if you want, but easily switch to using an ExecutorService. Commented Jun 22, 2011 at 3:34

3 Answers 3

2

The text book way to do this could be something like this:

class GetDataObj implements Callable<Data> {
    public Data call(){
        //get data
        return data; 
    }
}

then

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();

Note that when you iterate through futures, the get() method will block until the result is available for that DataObj. If you want to wait until all data are available, this is fine.

Sign up to request clarification or add additional context in comments.

Comments

1

If you call object.myMethod(), the method will run in the caller thread.

You have to start() the thread to make it run, not call the run() method.

A think you can do, is rewriting your object so that the myMethod() method launch a new thread. So you can use your objects exactly the same as actually. But if myMethod return something, that change, because you have to wait for the thread to terminate befor

Comments

1

I think it would be best to use a thread pool to get data from the objects. Therefore you would need each object to implement Runnable. See thread pools.

If you pass a reference to a queue to the objects once they have got the data they can place it in the queue. The main thread can then just take the data off the queue when it is ready. See the producer-consumer pattern.

An example of this is:

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();

You would need to have a for-loop for more than one object.

Hope this helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.