скажем, у меня есть метод doWork()
. Как я могу назвать это из отдельного потока (а не основного потока).
Как вызвать метод с отдельным потоком в Java?
Ответ 1
Создайте класс, реализующий интерфейс Runnable
. Поместите код, который вы хотите запустить в методе run()
, - метод, который вы должны записать, чтобы соответствовать интерфейсу Runnable
. В своем "основном" потоке создайте новый класс Thread
, передав конструктору экземпляр вашего Runnable
, а затем вызовите start()
на нем. start
сообщает JVM делать магию для создания нового потока, а затем вызывает ваш метод run
в этом новом потоке.
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();
}
}
Посмотрите Java concurrency учебник, чтобы начать.
Если ваш метод будет вызываться часто, то, возможно, не стоит создавать новый поток каждый раз, поскольку это дорогостоящая операция. Вероятно, лучше всего использовать пул потоков. Посмотрите классы Future
, Callable
, Executor
в пакете java.util.concurrent
.
Ответ 2
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
или же
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
или же
new Thread(() -> {
// code goes here.
}).start();
или же
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
или же
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
Ответ 3
В Java 8 вы можете сделать это с помощью одной строки кода.
Если ваш метод не принимает никаких параметров, вы можете использовать ссылку на метод:
new Thread(MyClass::doWork).start();
В противном случае вы можете вызвать метод в выражении лямбда:
new Thread(() -> doWork(someParam)).start();
Ответ 4
Еще одна более быстрая возможность вызывать вещи (например, DialogBoxes и MessageBoxes и создавать отдельные потоки для не-потоковых безопасных методов) заключается в использовании выражения Lamba Expression
new Thread(() -> {
"code here"
}).start();
Ответ 5
Когда-то я написал простой класс утилиты, который использует службу-исполнитель JDK5 и выполняет определенные процессы в фоновом режиме. Поскольку doWork() обычно имеет возвращаемое значение void, вы можете использовать этот класс утилиты для его выполнения в фоновом режиме.
См. в этой статье, где я зарегистрировал эту утилиту.
Ответ 6
Чтобы добиться этого с помощью RxJava 2.x, вы можете использовать:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
Метод subscribeOn()
указывает, какой планировщик запускает действие: RxJava имеет несколько предопределенных планировщиков, включая Schedulers.io()
, у которого есть пул потоков, предназначенный для операций ввода-вывода, и Schedulers.computation()
, который предназначен для интенсивных операций ЦП.
Ответ 7
Если вы используете хотя бы Java 8, вы можете использовать метод runAsync
из класса CompletableFuture
CompletableFuture.runAsync(() -> {...});
Если вам нужно вернуть результат, используйте вместо него supplyAsync
CompletableFuture.supplyAsync(() -> 1);