0

I am pretty new to using multithreading, but I want to invoke a method asynchronously (in a separate Thread) rather than invoking it synchronously. The basic idea is that I'm creating a socket server with an object in memory, so for each client I will have to run something like object.getStuff() asynchronously.

The two constructs I found were:

  1. having the class implement Runnable and threading this and
  2. declaring a runnable class within a method.

Additionally this method needs a return value- will it be necessary to use Executor and Callable to achieve this? Could someone point me in the right direction for implementing this?

I have tried implement option 2, but this doesn't appear to be processing concurrently:

public class Test {
    private ExecutorService exec = Executors.newFixedThreadPool(10);

    public Thing getStuff(){

        class Getter implements Callable<Thing>{
            public Thing call(){
                //do collection stuff
                return Thing;
            }
        }

        Callable<Thing> callable = new Getter();
        Future<Thing> future = exec.submit(callable);
        return future.get();   
    }    
}

I am instantiating a single test object for the server and calling getStuff() for each client connection.

not_rafay
  • 181
  • 1
  • 14
  • 1
    It's hard to answer your question without your code fragments. Maybe you can find something useful from here? http://stackoverflow.com/questions/9148899/returning-value-from-thread – Chong Tang Jul 21 '15 at 13:08
  • 1
    _I am looking to thread a method calls of an object versus the object itself._ That doesn't mean anything. Show us code, tell us what you expected your code to do, ask us why it does something else instead. Or, show us code, tell us why you have doubts about it, ask us if there's a better way. – Solomon Slow Jul 21 '15 at 13:19
  • How do you know that, "this doesn't appear to be processing concurrently?" The way I read it, the thread that calls `test.getStuff()` is going to submit its `callable` task, and then it will do _nothing_ until the task completes. `future.get()` does not return until the task is finished. – Solomon Slow Jul 21 '15 at 22:48
  • I created an instance of Test and called .getStuff() in succession (I put a timer in the function) and it is performing as you said. Is there a way to implement this so that method calls to .getStuff() are processed concurrently? (sorry if these rudimentary, I am only familiar with the basic implementation of using the executor). – not_rafay Jul 22 '15 at 11:38

4 Answers4

2

Threading Tutorial

The Java tutorial on concurrency has a good section on this. It's at https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html. Essentially, you can either implement Runnable or Callable, or inherit from Thread.

Subclassing Thread

You can write a class, including an anonymous inner class, that extends Thread. Instantiate it, then invoke the start() method.

public class MyThread extends Thread {
  public void run() {
    System.out.println("This is a thread");
  }
  public static void main(String[] args) {
    MyThread m = new MyThread();
    m.start();
  }
}

Implementing Runnable

You can write a class that implements Runnable, then wrap an instance in a Thread and invoke start(). Very much like the previous.

public class MyRunnable implements Runnable {
  public void run() {
    System.out.println("This is a thread");
  }
  public static void main(String[] args) {
    MyRunnable r = new MyRunnable();
    (new Thread(r)).start();
  }
}

Return Value

Runnable doesn't allow for return values. If you need that, you need to implement Callable instead. Callable looks a lot like Runnable, except you override the call() method instead of the run() method, and you need to give it to an ExecutorService.

public class MyCallable implements Callable<Integer> {
  public Integer call() {
    System.out.println("A thread using Callable<Integer>");
    return 42;
  }
  public static void main(String[] args) {
    MyCallable c = new MyCallable();
    Future<Integer> f = Executors.newSingleThreadExecutor().submit(c));
    System.out.println("The thread returned: " +
      f.get());
  }
}
Erick G. Hagstrom
  • 4,873
  • 1
  • 24
  • 38
  • OP never mentioned extending the `Thread` class. Why would you want to put that old-fashioned notion into his/her head? – Solomon Slow Jul 21 '15 at 13:34
  • Because, @jameslarge, it flows naturally from there to implementing Runnable wrapped in a Thread. Thread, after all, implements Runnable itself. Really, though, they're both old-fashioned. Callable/Executor is the currently fashionable method. – Erick G. Hagstrom Jul 21 '15 at 13:36
  • _it flows naturally..._ The `Thread` class never would have had a public `run()` method if the Java implementors had known back then what they know today. It also would "flow naturally" if you started by explaining lambda expressions, and then worked your way toward threading from there. – Solomon Slow Jul 21 '15 at 15:17
  • @jameslarge I do not believe that word means what you think it means :-) – Erick G. Hagstrom Jul 21 '15 at 15:41
  • 1
    That's inconceivable! – Solomon Slow Jul 21 '15 at 16:33
1

The two constructs I found were 1) having the class implement Runnable and threading 'this' and 2) declaring a runnable class within a method.

Option (2) probably is better. Most programs would be improved if they had more classes, not fewer. Each named entity in a program—each package, class, method, whatever—should have just one responsibility. In your option (1), you are asking the class to do two things.

For your option (2), you don't actually have to declare a whole class. You can either use an anonymous inner class, or if you can go with Java8 all the way, you can use a lambda expression. Google for either one to learn more.

Additionally this method needs a return value.

The classic way, is for the Runnable object to return the value through one of its own fields before the thread terminates. Then the parent thread, can examine the object and get the return value afterward.

Will it be necessary to use Executor and Callable to achieve this?

Necessary? A lot of people think that ExecutorService is a Good Thing.

Sounds like you are creating a server that serves multiple clients. Do these clients continually connect and disconnect? The advantage of using a thread pool (i.e., ThreadPoolExecutor) is that it saves your program from continually creating and destroying threads (e.g., every time a client connects/disconnects). Creating and destroying threads is expensive. If you have a lot of clients connecting and disconnecting, then using a thread pool could make a big difference in the performance of your server.

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
  • After some testing I couldn't this to work. I edited the original post with some sample code similar to my implementation. Guessing it has to do with the executor called within the method? – not_rafay Jul 21 '15 at 21:47
0

Creating and managing threads by yourself is generally bad approach. As you already pointed - use Executors utility class to create executor and submit Callables to it.

Bananan
  • 613
  • 5
  • 19
  • Creating your own _thread pool_ is a bad idea because that's re-inventing a wheel, but not every program that needs threads needs a thread pool. – Solomon Slow Jul 21 '15 at 13:33
0
public class RunWResult implements Runable{
    private volatile ResultType var;

    //the thread method
    public void run(){
        ...

        //generate a result and save it to var
        var = someResult();

        //notify waiting threads that a result has been generated
        synchronized(this){
            notify();
        }
    }

    public ResultType runWithResult(){
        //run the thread generating a result
        Thread t = new Thread(this);
        t.start();

        //wait for t to create a result
        try{
            wait();
        }catch(InterruptedException e){}

        //return the result
        return var;
    }
}
  • This is a good start. The server will handle client threads, but the server itself has objects for lookups to outside sources (the reason for this is that each source has authentication protocols, message formatting, etc.). – not_rafay Jul 21 '15 at 13:57