Reputation: 181
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:
this
and 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.
Upvotes: 0
Views: 1854
Reputation: 4945
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
.
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();
}
}
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();
}
}
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());
}
}
Upvotes: 2
Reputation:
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;
}
}
Upvotes: 0
Reputation: 27125
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.
Upvotes: 1
Reputation: 609
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.
Upvotes: 0