Os tópicos devem começar na mesma fração de segundo. Eu entendo, se você fizer thread1.start()
isso, vai demorar alguns milissegundos antes da próxima execução dethread2.start()
.
É mesmo possível ou impossível?
Os tópicos devem começar na mesma fração de segundo. Eu entendo, se você fizer thread1.start()
isso, vai demorar alguns milissegundos antes da próxima execução dethread2.start()
.
É mesmo possível ou impossível?
Respostas:
Para iniciar os threads exatamente ao mesmo tempo (pelo menos da melhor forma possível), você pode usar um CyclicBarrier :
// We want to start just 2 threads at the same time, but let's control that
// timing from the main thread. That's why we have 3 "parties" instead of 2.
final CyclicBarrier gate = new CyclicBarrier(3);
Thread t1 = new Thread(){
public void run(){
gate.await();
//do stuff
}};
Thread t2 = new Thread(){
public void run(){
gate.await();
//do stuff
}};
t1.start();
t2.start();
// At this point, t1 and t2 are blocking on the gate.
// Since we gave "3" as the argument, gate is not opened yet.
// Now if we block on the gate from the main thread, it will open
// and all threads will start to do stuff!
gate.await();
System.out.println("all threads started");
Não precisa ser um CyclicBarrier
, você também pode usar um CountDownLatch
ou até mesmo um cadeado.
Isso ainda não pode garantir que eles sejam iniciados exatamente ao mesmo tempo em JVMs padrão, mas você pode chegar bem perto. Chegar bem perto ainda é útil quando você faz, por exemplo, testes de desempenho. Por exemplo, se você está tentando medir o rendimento de uma estrutura de dados com um número diferente de threads atingindo-a, você deseja usar esse tipo de construção para obter o resultado mais preciso possível.
Em outras plataformas, iniciar threads exatamente pode ser um requisito muito válido btw.
CreateEvent
. msdn.microsoft.com/en-us/library/ms686364%28VS.85%29.aspx
Não é possível, pelo menos em um computador de núcleo único. Mas por que você quer isso? Mesmo se você pudesse iniciar dois threads exatamente no mesmo segundo, eles progrediriam de forma diferente porque o agendamento não está sob seu controle.
Editar: (em resposta a alguns dos comentários) É um requisito perfeitamente válido sincronizar o estado ou o progresso de vários threads e CyclicBarrier
é uma ótima ferramenta. Eu respondi à pergunta se é possível iniciar vários threads exatamente ao mesmo tempo . CyclicBarrier
irá garantir que os threads continuem quando estiverem exatamente no estado desejado, mas não garante que eles serão iniciados ou retomados exatamente ao mesmo tempo, embora possa ser bem próximo. Não há menção das necessidades de sincronização na pergunta.
Você pode usar um CountDownLatch para isso. Veja abaixo um exemplo. Embora t1 e t2 sejam iniciados, esses encadeamentos continuam esperando até que o encadeamento principal faça a contagem regressiva da trava. O número de contagens regressivas necessárias é mencionado no construtor. A trava de contagem regressiva também pode ser usada para esperar que os encadeamentos concluam a execução para que o encadeamento principal possa prosseguir (o caso inverso). Esta classe foi incluída desde Java 1.5.
import java.util.concurrent.CountDownLatch;
public class ThreadExample
{
public static void main(String[] args)
{
CountDownLatch latch = new CountDownLatch(1);
MyThread t1 = new MyThread(latch);
MyThread t2 = new MyThread(latch);
new Thread(t1).start();
new Thread(t2).start();
//Do whatever you want
latch.countDown(); //This will inform all the threads to start
//Continue to do whatever
}
}
class MyThread implements Runnable
{
CountDownLatch latch;
public MyThread(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
latch.await(); //The thread keeps waiting till it is informed
} catch (InterruptedException e) {
e.printStackTrace();
}
//Do the actual thing
}
}