digamos que eu tenho um método doWork()
. Como eu o chamo de um thread separado (não do thread principal).
digamos que eu tenho um método doWork()
. Como eu o chamo de um thread separado (não do thread principal).
Respostas:
Crie uma classe que implemente a Runnable
interface. Coloque o código que você deseja executar no run()
método - esse é o método que você deve escrever para estar em conformidade com a Runnable
interface. No seu segmento "principal", crie uma nova Thread
classe, passando ao construtor uma instância do seu e Runnable
, em seguida, chame start()
-o. start
diz à JVM para fazer a mágica para criar um novo encadeamento e, em seguida, chame seu run
método nesse novo encadeamento.
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();
}
}
Dê uma olhada no tutorial de simultaneidade do Java para começar.
Se seu método for chamado com frequência, pode não valer a pena criar um novo encadeamento a cada vez, pois essa é uma operação cara. Provavelmente seria melhor usar algum tipo de pool de threads. Ter um olhar para Future
, Callable
, Executor
classes no java.util.concurrent
pacote.
run()
método não usa parâmetros, portanto você não pode passar uma variável para lá. Sugiro que você o passe no construtor - editarei minha resposta para mostrar isso.
new Thread() { public void run() {myMethod();}}.start();
caminho, é o mais curto?
Runnable
- mine é uma classe que se estende Runnable
. E porque fiz isso, tenho meu próprio construtor, que passa o estado para o objeto instanciado.
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
});
t1.start();
ou
new Thread(new Runnable() {
@Override
public void run() {
// code goes here.
}
}).start();
ou
new Thread(() -> {
// code goes here.
}).start();
ou
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
ou
Executors.newCachedThreadPool().execute(new Runnable() {
@Override
public void run() {
myCustomMethod();
}
});
run()
?
No Java 8, você pode fazer isso com uma linha de código.
Se o seu método não usar nenhum parâmetro, você poderá usar uma referência de método:
new Thread(MyClass::doWork).start();
Caso contrário, você pode chamar o método em uma expressão lambda:
new Thread(() -> doWork(someParam)).start();
->
significa?
Celery task queue
para para o material assíncrono
Outra opção mais rápida de chamar coisas (como DialogBoxes e MessageBoxes e criar threads separados para métodos seguros não relacionados a threads) seria usar a expressão Lamba
new Thread(() -> {
"code here"
}).start();
Algum tempo atrás, eu escrevi uma classe de utilitário simples que usa o serviço executor JDK5 e executa processos específicos em segundo plano. Como doWork () normalmente teria um valor de retorno nulo, convém usar essa classe de utilitário para executá-lo em segundo plano.
Veja este artigo onde eu havia documentado esse utilitário.
Para conseguir isso com o RxJava 2.x, você pode usar:
Completable.fromAction(this::dowork).subscribeOn(Schedulers.io().subscribe();
O subscribeOn()
método especifica em qual agendador executar a ação - o RxJava possui vários agendadores predefinidos, incluindo Schedulers.io()
um conjunto de encadeamentos destinado a operações de E / S e Schedulers.computation()
qual é destinado a operações intensivas da CPU.
Se você estiver usando pelo menos Java 8, poderá usar o método runAsync
da classe CompletableFuture
CompletableFuture.runAsync(() -> {...});
Se você precisa retornar um resultado use supplyAsync
vez
CompletableFuture.supplyAsync(() -> 1);