Потоки должны начинаться с той же секунды. Я понимаю, что если вы выполните thread1.start()
, это займет несколько миллисекунд до следующего выполнения thread2.start()
.
Возможно ли это или невозможно?
Потоки должны начинаться с той же секунды. Я понимаю, что если вы выполните thread1.start()
, это займет несколько миллисекунд до следующего выполнения thread2.start()
.
Возможно ли это или невозможно?
Чтобы начать потоки ровно в одно и то же время (по крайней мере, насколько это возможно), вы можете использовать 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.
Это невозможно, по крайней мере, на одном основном компьютере. Но почему вы этого хотите? Даже если вы смогли запустить два потока ровно в одну секунду, они будут работать по-другому, потому что планирование не находится под вашим контролем.
Изменить: (В ответ на некоторые комментарии). Это абсолютно правильное требование для синхронизации состояния или выполнения нескольких потоков, а CyclicBarrier
- отличный инструмент. Я ответил на вопрос, можно ли запускать несколько потоков ровно в одно и то же время. CyclicBarrier
гарантирует, что потоки будут выполняться, когда они находятся точно в желаемом состоянии, но это не гарантирует, что они начнутся или возобновятся точно в одно и то же время, хотя это может быть довольно близко. В этом вопросе не упоминается о необходимости синхронизации.
Для этого можно использовать 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
}
}