views:

141

answers:

4

I understand the concept behind threading and have written threads in other languages, but I am having trouble understanding how to adapt them to my needs in java.

Basicly at present I have a vector of objects, which are read in from a file sequentially. The file then has a list of events, which need to happen concurrently so waiting for one event to finish which takes 20-30 seconds is not an option.

There is only a couple of methods in the object which deal with these events. However from looking at tutorials, objects must extend/implement threads/runnable however if the object is in a thread making a method call to that object seems to happen sequentially anyway.

An y extra information would be appreciated as I am clearly missing something I am just not quite sure what!

So to summarise how can I execute a single method using a thread?

+5  A: 

To start a thread you call start() on an instance of Thread or a subclass thereof. The start() method returns immediately. At the same time, the other thread (the one incarnated by the Thread instance) takes off, and proceeds with executing the run() method of the Thread instance.

Managing threads is not as easy as it seems. For a smoother API, try using an Executor (see the classes in java.util.concurrent).

Thomas Pornin
I corrected the package name for you.
R. Bemrose
how would I specify that run() executes the correct methods? as I cant pass any parameters via run?
john
@john: You can inject whatever parameters you want into your Thread/Runnable's constructor.
Nelson
@john Please see my answer on how to make a Worker class that either invokes a method on your class or to actually process the data. If your class implements Runnable, then you can simply call executor.execute(this); and it will execute your class's run method in parallel to your file processing.
Lirik
A: 

Thomas has already given the technical details. I am going to try and focus on the logic.

Here is what I can suggest from my understanding of your problem.

Lets say you have a collection of objects of type X (or maybe even a mix of different types). You need to call methods foo and/or bar in these objects based on some event specified. So now, you maybe have a second collection that stores those.

So we have two List objects (one for the X objects and other for the events).

Now, we have a function execute that will take X, and the event, and call foo or bar. This execute method can be wrapped in a thread, and executed simultaneously. Each of these threads can take one object from the list, increment the counter, and execute foo/bar. Once done, check the counter, and take the next one from the list. You can have 5 or more of these threads working on the list.

So, as we see, the objects coming from file do not have to be the Thread objects.

You have to be very careful that the List and counter are synchronized. Much better data structures are possible. I am sticking to a crude one for ease of understanding.

Hope this helps.

Tanmay
A: 

The key to threads is to remember that each task that must be running must be in its own thread. Tasks executing in the same thread will execute sequentially. Dividing the concurrent tasks among separate threads will allow you to do your required cocurrent processing.

Rachel
While that's a good point, I'm not really sure that answers the question... Surely you can think of how to answer the part about dealing specifically with threads in Java?
Platinum Azure
+1  A: 

The best thing to do in Java is create another class that takes in the data you need to process and performs whatever you need it to perform:

    class Worker implements Runnable{

    Object mydata;
    Worker(Object data)
    {
        mydata = data;
    }

    @override
    void run()
    {
        //process the data
        System.out.println(data.toString());

        //or if you want to use your class then:
        YourClass yc = (YourClass)myData;
        yc.methodB();
    }
}

class YourClass
{
    private final ExecutorService executor = Executors.newCachedThreadPool();
    private ArrayList<Object> list;
    YourClass()
    {
        list = new ArrayList<Object>();
        list.add(new Object());
        ...
        ...
        list.add(new Object());
    }

    void methodA()
    {
        for(Object item : list )
        {
            // Create a new thread with the worker class taking the data
            executor.execute(new Worker(item));
        }
    }

    void methodB(){/*do something else here*/}
}

Note that instead of getting the data, you can pass the actual class that you need the method to be invoked on:

executor.execute(new Worker(new MyClass()));

In the run method of the Worker class you invoke whatever you need to invoke on MyClass... the executor creates a new thread and calls run on your Worker. Each Worker will run in a separate thread and it will be parallel.

Lirik
By the way: in methodA you can read your objects from file, execute a new Worker with each object that you obtained from the file, and continue to read more objects while the worker is processing the item.
Lirik
Thanks, that seems to be exactly the solution I am after, however, is there a way in which I can ensure that each time the method is called it runs using a new thread or one that has finished?
john
@john You are GUARANTEED that whenever you call execute it will run your method in a "new thread". To be more precise, the java documentation says that the "execute" method "executes the given task sometime in the future. The task may execute in a new thread or in an existing pooled thread." From your perspective there is no difference between an existing pooled thread or a new thread. "Sometime in the future" simply means that the thread scheduler decides when to run the thread (same as calling new Thread(...)).
Lirik