Как запустить два потока в "точно" в одно и то же время
Потоки должны начинаться с той же секунды. Я понимаю, что если вы выполните thread1.start()
, это займет несколько миллисекунд до следующего выполнения thread2.start()
.
Возможно ли это или невозможно?
Ответы
Ответ 1
Чтобы начать потоки ровно в одно и то же время (по крайней мере, насколько это возможно), вы можете использовать CyclicBarrier:
// We want to start just 2 threads at the same time, but let control that
// timing from the main thread. That 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");
Это не должно быть CyclicBarrier
, вы также можете использовать CountDownLatch
или даже блокировку.
Это все еще не может гарантировать, что они будут запускаться точно в одно время на стандартных JVM, но вы можете приблизиться. Приближение довольно полезно, когда вы делаете, например, тесты производительности. Например, если вы пытаетесь измерить пропускную способность структуры данных с различным количеством потоков, попавших в нее, вы хотите использовать эту конструкцию для получения максимально точного результата.
На других платформах начальные потоки точно могут быть очень действительным требованием btw.
Ответ 2
Это невозможно, по крайней мере, на одном основном компьютере. Но почему вы этого хотите? Даже если вы смогли запустить два потока ровно в одну секунду, они будут работать по-другому, потому что планирование не находится под вашим контролем.
Изменить: (В ответ на некоторые комментарии). Это абсолютно правильное требование для синхронизации состояния или выполнения нескольких потоков, а CyclicBarrier
- отличный инструмент. Я ответил на вопрос, можно ли запускать несколько потоков ровно в одно и то же время. CyclicBarrier
гарантирует, что потоки будут выполняться, когда они находятся точно в желаемом состоянии, но это не гарантирует, что они начнутся или возобновятся точно в одно и то же время, хотя это может быть довольно близко. В этом вопросе не упоминается о необходимости синхронизации.
Ответ 3
Для этого можно использовать CountDownLatch.
Ниже приведен пример.
Хотя t1 и t2 запускаются, эти нити продолжают ждать, пока основной поток не закроет защелку. Количество требуемых обратных отсчетов указано в конструкторе. Защелка обратного отсчета также может использоваться для ожидания завершения потоков, чтобы основной поток мог продолжить (обратный регистр). Этот класс был включен с 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
}
}
Ответ 4
- Как я понимаю, JVM в основном делегирует этот материал операционной системе. Таким образом, ответ будет специфичным для ОС.
- Это явно невозможно на однопроцессорных машинах.
- Это сложнее в отношении многопроцессорной машины. Согласно Относительность одновременности, "невозможно в абсолютном смысле сказать, происходят ли одновременно два события, если эти события разделены в космосе." Независимо от того, насколько близки ваши процессоры, они разделены в пространстве.
- Если вы можете принять относительную одновременность, то, вероятно, проще просто имитировать ее, используя методы, обсуждаемые в других ответах.