177

let's say I have a method doWork(). How do I call it from a separate thread (not the main thread).

Louis Rhys
  • 34,517
  • 56
  • 153
  • 221
  • There happen to be some examples over on this recent related question: [killing an infinite loop in java](http://stackoverflow.com/questions/3489467/killing-an-infinite-loop-in-java) – Greg Hewgill Aug 15 '10 at 22:41
  • http://stackoverflow.com/questions/36832094/bring-control-from-application-to-java-frame I have a similar issue pls help me to solve this – Sruthi Acg Apr 25 '16 at 05:31
  • You may also like to take a look at Reactive Java http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/ for asynchronous tasks – Nathan Jan 06 '17 at 01:31

8 Answers8

267
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        // code goes here.
    }
});  
t1.start();

or

new Thread(new Runnable() {
     @Override
     public void run() {
          // code goes here.
     }
}).start();

or

new Thread(() -> {
    // code goes here.
}).start();

or

Executors.newSingleThreadExecutor().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});

or

Executors.newCachedThreadPool().execute(new Runnable() {
    @Override
    public void run() {
        myCustomMethod();
    }
});
Erikas
  • 1,006
  • 11
  • 22
MANN
  • 3,360
  • 1
  • 17
  • 18
  • 1
    This worked perfectly for what I was doing. Needed to run a webservice and updating a progress bar concurrently using the observer pattern. – dpi Feb 15 '14 at 15:20
  • @Ashish: Please explain what and why has been edited? – MANN Oct 30 '14 at 14:55
  • 1
    @AshishAggarwal: Looks weird to me when someone does that without taking permission from the author! – MANN Oct 31 '14 at 15:25
  • @MANN can you explain why you use run method in Thread parameter? any better performance? – Asif Mushtaq Oct 05 '15 at 14:32
  • @UnKnown no, this is an inline implementation of the `Runnable` interface. You must implement the `run()` method so that `Thread` has something to run. – P.Péter Dec 03 '15 at 12:13
  • 5
    Do we need to explicitly terminate the thread? Isn't there a risk of creating a memory leak by not explicitly terminating the thread? Or does the thread terminate when it's done with `run()`? – theyuv Apr 15 '16 at 18:59
  • 3
    In Java 8 and later we can replace `new Runnable() {...}` verbose stuff with `() -> myCustomMethod()` – chill appreciator Oct 16 '19 at 23:05
  • it is a really nice answer. brief and clean. – Amir Aug 24 '22 at 11:17
159

Create a class that implements the Runnable interface. Put the code you want to run in the run() method - that's the method that you must write to comply to the Runnable interface. In your "main" thread, create a new Thread class, passing the constructor an instance of your Runnable, then call start() on it. start tells the JVM to do the magic to create a new thread, and then call your run method in that new thread.

public class MyRunnable implements Runnable {

    private int var;

    public MyRunnable(int var) {
        this.var = var;
    }

    public void run() {
        // code in the other thread, can reference "var" variable
    }
}

public class MainThreadClass {
    public static void main(String args[]) {
        MyRunnable myRunnable = new MyRunnable(10);
        Thread t = new Thread(myRunnable)
        t.start();
    }    
}

Take a look at Java's concurrency tutorial to get started.

If your method is going to be called frequently, then it may not be worth creating a new thread each time, as this is an expensive operation. It would probably be best to use a thread pool of some sort. Have a look at Future, Callable, Executor classes in the java.util.concurrent package.

Noel M
  • 15,812
  • 8
  • 39
  • 47
  • 1
    what if there is a variable you would like to pass? – Louis Rhys Aug 16 '10 at 07:21
  • 10
    The `run()` method takes no parameters, so you can't pass a variable there. I'd suggest that you pass it in the constructor - I'll edit my answer to show that. – Noel M Aug 16 '10 at 08:15
  • 1
    Is there a short way for calling 1 method in a different thread? I know of the `new Thread() { public void run() {myMethod();}}.start();` way, is that the shortest? – Steven Roose Nov 29 '12 at 22:38
  • @NoelM can you explain difference between yours and MANN's answer? – Asif Mushtaq Oct 05 '15 at 14:40
  • 2
    MANN's answer uses an anonymous implementation of `Runnable` - mine is a class that extends `Runnable`. And because I've done that I have my own constructor which passes state into the instantiated object. – Noel M Oct 06 '15 at 08:28
75

In Java 8 you can do this with one line of code.

If your method doesn't take any parameters, you can use a method reference:

new Thread(MyClass::doWork).start();

Otherwise, you can call the method in a lambda expression:

new Thread(() -> doWork(someParam)).start();
Aaron Cohn
  • 901
  • 7
  • 10
  • sorry to bring this back but what exactly does the `->` mean? – Kyle Aug 25 '15 at 13:50
  • 2
    That is the syntax used to create a lambda expression. Take a look at these links for more info: [What does '->' do in Java?](http://stackoverflow.com/a/20771467/1852614), and [The Java™ Tutorials - Lambda Expressions](http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html) – Aaron Cohn Aug 25 '15 at 19:38
  • @AaronCohn great stuff man! Do you know any alternatives to threads in Java? I come from the Python world, whre we would use `Celery task queue` for for asynchronous stuff – CESCO Nov 05 '15 at 18:10
  • Java has [higher level abstractions for dealing with Threads](https://docs.oracle.com/javase/tutorial/essential/concurrency/highlevel.html), but maybe you're looking for something more like [Akka](http://akka.io/)? – Aaron Cohn Nov 06 '15 at 18:52
  • My method throws exception. How can I throw an exception from a thread in your first example? – Hrvoje T Mar 11 '22 at 15:22
18

If you are using at least Java 8 you can use method runAsync from class CompletableFuture

CompletableFuture.runAsync(() -> {...});

If you need to return a result use supplyAsync instead

CompletableFuture.supplyAsync(() -> 1);
k13i
  • 4,011
  • 3
  • 35
  • 63
8

Another quicker option to call things (like DialogBoxes and MessageBoxes and creating separate threads for not-thread safe methods) would be to use the Lamba Expression

  new Thread(() -> {
                      "code here"
            }).start();
Rohan Sawant
  • 938
  • 1
  • 11
  • 18
4

To achieve this with RxJava 2.x you can use:

Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();

The subscribeOn() method specifies which scheduler to run the action on - RxJava has several predefined schedulers, including Schedulers.io() which has a thread pool intended for I/O operations, and Schedulers.computation() which is intended for CPU intensive operations.

Clyde
  • 7,389
  • 5
  • 31
  • 57
2

Sometime ago, I had written a simple utility class that uses JDK5 executor service and executes specific processes in the background. Since doWork() typically would have a void return value, you may want to use this utility class to execute it in the background.

See this article where I had documented this utility.

raja kolluru
  • 602
  • 4
  • 5
1

In java 8 you can call it through method reference by creating new thread.

Thread t = new Thread(new YourClassName::doWork);
t.start();

you can refer static mathod also, in that case you don't need to use new operator.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 26 '23 at 09:37