Wątki powinny rozpoczynać się w tym samym ułamku sekundy. Rozumiem, że jeśli to zrobisz thread1.start()
, kolejne uruchomienie zajmie kilka milisekund thread2.start()
.
Czy to w ogóle możliwe czy niemożliwe?
Wątki powinny rozpoczynać się w tym samym ułamku sekundy. Rozumiem, że jeśli to zrobisz thread1.start()
, kolejne uruchomienie zajmie kilka milisekund thread2.start()
.
Czy to w ogóle możliwe czy niemożliwe?
Odpowiedzi:
Aby rozpocząć wątki dokładnie w tym samym czasie (przynajmniej tak dobrze, jak to możliwe), możesz użyć 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");
To nie musi być a CyclicBarrier
, możesz też użyć a, CountDownLatch
a nawet zamka.
Wciąż nie można zagwarantować, że zostaną uruchomione dokładnie w tym samym czasie na standardowych maszynach JVM, ale można podejść całkiem blisko. Podejście dość blisko jest nadal przydatne, na przykład podczas testów wydajności. Na przykład, jeśli próbujesz zmierzyć przepustowość struktury danych z różną liczbą trafiających w nią wątków, chcesz użyć tego rodzaju konstrukcji, aby uzyskać jak najdokładniejszy wynik.
Na innych platformach, nici zaczynające dokładnie może być bardzo ważny wymóg btw.
CreateEvent
. msdn.microsoft.com/en-us/library/ms686364%28VS.85%29.aspx
Nie jest to możliwe, przynajmniej na komputerze jednordzeniowym. Ale dlaczego tego chcesz? Nawet jeśli byłbyś w stanie uruchomić dwa wątki dokładnie w tej samej sekundzie, będą one postępować inaczej, ponieważ planowanie nie jest pod Twoją kontrolą.
Edycja: (w odpowiedzi na niektóre komentarze) Jest to całkowicie ważny wymóg synchronizacji stanu lub postępu wielu wątków i CyclicBarrier
jest świetnym narzędziem. Odpowiedziałem na pytanie, czy możliwe jest rozpoczęcie wielu wątków dokładnie w tym samym czasie . CyclicBarrier
zagwarantuje, że wątki będą kontynuowane, gdy znajdą się dokładnie w pożądanym stanie, ale nie gwarantuje, że zostaną uruchomione lub wznowione dokładnie w tym samym czasie, chociaż może być dość blisko. W pytaniu nie ma wzmianki o potrzebach synchronizacji.
Możesz do tego użyć CountDownLatch. Poniżej próbkę. Chociaż t1 i t2 są uruchomione, te wątki czekają, aż główny wątek odliczy zatrzask. Liczba wymaganych odliczeń jest podana w konstruktorze. Zatrzask odliczania może być również używany do oczekiwania na zakończenie wykonywania wątków, aby wątek główny mógł przejść dalej (przypadek odwrotny). Ta klasa została uwzględniona od wersji 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
}
}