Les threads devraient commencer à la même fraction de seconde. Je comprends que si vous le faites thread1.start()
, il faudra quelques millisecondes avant la prochaine exécution de thread2.start()
.
Est-ce même possible ou impossible?
Les threads devraient commencer à la même fraction de seconde. Je comprends que si vous le faites thread1.start()
, il faudra quelques millisecondes avant la prochaine exécution de thread2.start()
.
Est-ce même possible ou impossible?
Réponses:
Pour démarrer les threads exactement au même moment (au moins aussi bon que possible), vous pouvez utiliser un 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");
Cela ne doit pas nécessairement être un CyclicBarrier
, vous pouvez également utiliser un CountDownLatch
ou même un verrou.
Cela ne permet toujours pas de s'assurer qu'ils sont démarrés exactement au même moment sur les JVM standard, mais vous pouvez vous en approcher assez. Se rapprocher est toujours utile lorsque vous effectuez par exemple des tests de performances. Par exemple, si vous essayez de mesurer le débit d'une structure de données avec un nombre différent de threads qui l'atteignent, vous souhaitez utiliser ce type de construction pour obtenir le résultat le plus précis possible.
Sur d'autres plates-formes, démarrer exactement les threads peut être une exigence très valide btw.
CreateEvent
. msdn.microsoft.com/en-us/library/ms686364%28VS.85%29.aspx
Ce n'est pas possible, du moins sur un ordinateur à un seul cœur. Mais pourquoi veux-tu ça? Même si vous avez pu démarrer deux threads exactement à la même seconde, ils progresseront différemment car la planification n'est pas sous votre contrôle.
Edit: (En réponse à certains des commentaires) C'est une exigence parfaitement valide pour synchroniser l'état ou la progression de plusieurs threads et CyclicBarrier
c'est un excellent outil. J'ai répondu à la question de savoir s'il est possible de démarrer plusieurs threads exactement en même temps . CyclicBarrier
garantira que les threads se déroulent quand ils sont exactement à l'état souhaité, mais cela ne garantit pas qu'ils démarreront ou reprendront exactement au même moment, bien que cela puisse être assez proche. Il n'y a aucune mention des besoins de synchronisation dans la question.
Vous pouvez utiliser un CountDownLatch pour cela. Veuillez trouver ci-dessous un échantillon. Bien que t1 et t2 soient démarrés, ces threads continuent d'attendre jusqu'à ce que le thread principal décompte le verrou. Le nombre de comptes à rebours requis est mentionné dans le constructeur. Le verrou du compte à rebours peut également être utilisé pour attendre la fin de l'exécution des threads afin que le thread principal puisse continuer (le cas inverse). Cette classe est incluse depuis 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
}
}