简体   繁体   中英

java threading method within object with return value

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.

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

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 (ie, ThreadPoolExecutor ) is that it saves your program from continually creating and destroying threads (eg, 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.

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

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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