17

I'm writing small app and now I discovered a problem. I need to call one(later maybe two) method (this method loads something and returns the result) without lagging in window of app.

I found classes like Executor or Callable, but I don't understand how to work with those ones.

Can you please post any solution, which helps me?

Thanks for all advices.

Edit: The method MUST return the result. This result depends on parametrs. Something like this:

public static HtmlPage getPage(String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        return webClient.getPage(page);
}

This method works about 8-10 seconds. After execute this method, thread can be stopped. But I need to call the methods every 2 minutes.

Edit: I edited code with this:

public static HtmlPage getPage(final String page) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
    Thread thread = new Thread() {
        public void run() {
            try {
                loadedPage = webClient.getPage(page);
            } catch (FailingHttpStatusCodeException | IOException e) {
                e.printStackTrace();
            }
        }
    };
    thread.start();
    try {
        return loadedPage;
    } catch (Exception e) {
        return null;
    }

}

With this code I get error again (even if I put return null out of catch block).

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Sk1X1
  • 1,305
  • 5
  • 22
  • 50
  • 1
    [`Executor`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html) and [`ExecutorService`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html) have examples in the javadoc. And [a topic](http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html) on the *concurrency* thread in the official tutorial. That's where I start. You should ask a new question if you don't understand something *specific* in those materials, or if you're stuck having used the information in them. – millimoose Apr 07 '13 at 20:03
  • I saw the examples, bud I can't achieve what I want. – Sk1X1 Apr 07 '13 at 21:33
  • 1
    I *think* what you're looking for [`ExecutorService.submit()`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.util.concurrent.Callable)) with a `Callable`, so focus on the documentation for those and related classes/methods. `submit()` should return a `Future` which will let you do something (like update the UI) when the result is available. – millimoose Apr 07 '13 at 21:50
  • I'll see on this, thanks. – Sk1X1 Apr 08 '13 at 10:07

3 Answers3

39

Since Java 8 you can use shorter form:

new Thread(() -> {
    // Insert some method call here.
}).start();

Update: Also, you could use method reference:

class Example {
    
    public static void main(String[] args){
        new Thread(Example::someMethod).start();
    }
    
    public static void someMethod(){
        // Insert some code here
    }
    
}

You are able to use it when your argument list is the same as in required @FunctionalInterface, e.g. Runnable or Callable.

Update 2: I strongly recommend utilizing java.util.concurrent.Executors#newSingleThreadExecutor() for executing fire-and-forget tasks.

Example:

Executors
    .newSingleThreadExecutor()
    .submit(Example::someMethod);

See more: Platform.runLater and Task in JavaFX, Method References.

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
28

Firstly, I would recommend looking at the Java Thread Documentation.

With a Thread, you can pass in an interface type called a Runnable. The documentation can be found here. A runnable is an object that has a run method. When you start a thread, it will call whatever code is in the run method of this runnable object. For example:

Thread t = new Thread(new Runnable() {
         @Override
         public void run() {
              // Insert some method call here.
         }
});

Now, what this means is when you call t.start(), it will run whatever code you need it to without lagging the main thread. This is called an Asynchronous method call, which means that it runs in parallel to any other thread you have open, like your main thread. :)

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
christopher
  • 26,815
  • 5
  • 55
  • 89
7

In Java 8 if there is no parameters required you can use:

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

Or in case of parameters:

new Thread(() -> doWork(someParam))
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Rahul Singh
  • 19,030
  • 11
  • 64
  • 86
  • 1
    That's relative. The parameters are just hidden and it depends on the input parameters of the interface. When you write `new Thread(MyClass::doWork).start();` you could also write `new Thread(() ->doWork())` For Runabble has no input parameters. But if you require input from a variable that it's outside the closure, than yes, you can do the second way. – Saclyr Barlonium Nov 01 '16 at 14:53