powiedzmy, że mam metodę doWork()
. Jak mam to nazwać z osobnego wątku (nie głównego wątku).
powiedzmy, że mam metodę doWork()
. Jak mam to nazwać z osobnego wątku (nie głównego wątku).
Odpowiedzi:
Utwórz klasę, która implementuje Runnable
interfejs. Umieść kod, który chcesz uruchomić w run()
metodzie - to metoda, którą musisz napisać, aby była zgodna z Runnable
interfejsem. W swoim "głównym" wątku utwórz nową Thread
klasę, przekazując konstruktorowi twoją instancję Runnable
, a następnie wywołaj start()
ją. start
mówi JVM, aby wykonał magię, aby utworzyć nowy wątek, a następnie wywołać run
metodę w tym nowym wątku.
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();
}
}
Spójrz na samouczku współbieżności Java , aby zacząć.
Jeśli twoja metoda będzie często wywoływana, może nie być warto tworzyć za każdym razem nowego wątku, ponieważ jest to kosztowna operacja. Prawdopodobnie najlepiej byłoby użyć jakiejś puli wątków. Przyjrzeć się Future
, Callable
, Executor
klas w java.util.concurrent
pakiecie.
run()
Metoda bierze żadnych parametrów, więc nie można przekazać nie zmienną. Proponuję przekazać to w konstruktorze - edytuję swoją odpowiedź, aby to pokazać.
new Thread() { public void run() {myMethod();}}.start();
drogę, czy to najkrótsza?
Runnable
- moja to klasa, która rozszerza Runnable
. A ponieważ już to zrobiłem, mam swój własny konstruktor, który przekazuje stan do instancji obiektu.
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
lub
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
lub
new Thread(() -> {
// code goes here.
}).start();
lub
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
lub
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()
?
W Javie 8 możesz to zrobić za pomocą jednej linii kodu.
Jeśli Twoja metoda nie przyjmuje żadnych parametrów, możesz użyć odwołania do metody:
new Thread(MyClass::doWork).start();
W przeciwnym razie możesz wywołać metodę w wyrażeniu lambda:
new Thread(() -> doWork(someParam)).start();
->
oznacza?
Celery task queue
do rzeczy asynchronicznych
Inną szybszą opcją do wywoływania rzeczy (takich jak DialogBox i MessageBox oraz tworzenie oddzielnych wątków dla metod niegwątkowych) byłoby użycie wyrażenia Lamba
new Thread(() -> {
"code here"
}).start();
Jakiś czas temu napisałem prostą klasę narzędziową, która korzysta z usługi wykonawczej JDK5 i wykonuje określone procesy w tle. Ponieważ doWork () zazwyczaj ma wartość zwracaną przez void, możesz chcieć użyć tej klasy narzędziowej, aby wykonać ją w tle.
Zobacz ten artykuł, w którym udokumentowałem to narzędzie.
Aby to osiągnąć z RxJava 2.x, możesz użyć:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
Te subscribeOn()
określa, które scheduler metoda uruchomić akcję na - RxJava ma kilka predefiniowanych wyłącznika, tym Schedulers.io()
który posiada gwint basen przeznaczony dla I / O operacji, i Schedulers.computation()
który jest przeznaczony do intensywnej pracy procesora.
Jeśli używasz przynajmniej Java 8, możesz użyć metody runAsync
z klasy CompletableFuture
CompletableFuture.runAsync(() -> {...});
Jeśli chcesz zwrócić wynik, użyj supplyAsync
zamiast tego
CompletableFuture.supplyAsync(() -> 1);