Простой способ вызвать метод в новом потоке

Я пишу небольшое приложение и обнаружил проблему. Мне нужно вызвать один (позже, возможно, два) метода (этот метод что-то загружает и возвращает результат) без отставания в окне приложения.

Я нашел такие классы, как Executor или Callable, но не понимаю, как с ними работать.

Не могли бы вы опубликовать какое-либо решение, которое мне поможет?

Спасибо за все советы.

Изменить: метод ДОЛЖЕН возвращать результат. Этот результат зависит от параметров. Что-то вроде этого:

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

Этот метод работает около 8-10 секунд. После выполнения этого метода поток можно остановить. Но мне нужно вызывать методы каждые 2 минуты.

Изменить: я отредактировал код следующим образом:

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

}

С этим кодом я снова получаю ошибку (даже если я вынесу return null из блока catch).


person Sk1X1    schedule 07.04.2013    source источник
comment
Executor и _ 2_ есть примеры в javadoc. И тема о параллелизме ветка в официальном руководстве. Вот с чего я начинаю. Вам следует задать новый вопрос, если вы не понимаете чего-то конкретного в этих материалах или если вы застряли, воспользовавшись содержащейся в них информацией.   -  person millimoose    schedule 08.04.2013
comment
Я видел примеры, но я не могу добиться того, чего хочу.   -  person Sk1X1    schedule 08.04.2013
comment
Я думаю, что вы ищете _ 1_ с Callable<HtmlPage>, поэтому сосредоточьтесь на документации для этих и связанных классов / методов. submit() должен возвращать Future<HtmlPage>, который позволит вам что-то сделать (например, обновить пользовательский интерфейс), когда станет доступен результат.   -  person millimoose    schedule 08.04.2013
comment
Я посмотрю на это, спасибо.   -  person Sk1X1    schedule 08.04.2013


Ответы (3)


Во-первых, я бы порекомендовал посмотреть Документацию по потокам Java..

С помощью Thread вы можете передать тип интерфейса, называемый Runnable. Документацию можно найти здесь. Runnable - это объект, у которого есть run метод. Когда вы запускаете поток, он вызывает любой код из метода run этого исполняемого объекта. Например:

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

Это означает, что когда вы вызываете t.start(), он будет запускать любой код, который вам нужен, без задержки основного потока. Это называется вызовом метода Asynchronous, что означает, что он выполняется параллельно с любым другим открытым потоком, например с потоком main. :)

person christopher    schedule 07.04.2013
comment
Я пробую что-то подобное, но это не сработало (подробнее в следующем ответе) - person Sk1X1; 08.04.2013
comment
как передать аргумент вызывающему методу - person Uday A. Navapara; 25.09.2014

Начиная с Java 8 вы можете использовать более короткую форму:

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

Обновление: вы также можете использовать ссылку на метод:

class Example {

    public static void main(String[] args){
        new Thread(Example::someMethod).start();
    }

    public static void someMethod(){
        // Insert some code here
    }

}

Вы можете использовать его, если ваш список аргументов такой же, как и в обязательном @ FunctionalInterface, например Runnable или Callable.

Обновление 2: я настоятельно рекомендую использовать java.util.concurrent.Executors#newSingleThreadExecutor() для выполнения задач типа "запустил и забыл".

Пример:

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

См. Больше: Platform.runLater и Task в JavaFX, Ссылки на методы.

person Andrii Abramov    schedule 27.10.2015

В Java 8, если параметры не требуются, вы можете использовать:

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

Или в случае параметров:

new Thread(() -> doWork(someParam))
person Rahul Singh    schedule 01.11.2016
comment
Это относительно. Параметры просто скрыты и это зависит от входных параметров интерфейса. Когда вы пишете new Thread(MyClass::doWork).start();, вы также можете писать new Thread(() ->doWork()) Ибо Runabble не имеет входных параметров. Но если вам требуется ввод от переменной, которая находится за пределами замыкания, то да, вы можете сделать второй способ. - person Saclyr Barlonium; 01.11.2016