Подтвердить что ты не робот

Как запустить два потока в "точно" в одно и то же время

Потоки должны начинаться с той же секунды. Я понимаю, что если вы выполните thread1.start(), это займет несколько миллисекунд до следующего выполнения thread2.start().

Возможно ли это или невозможно?

4b9b3361

Ответ 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 в основном делегирует этот материал операционной системе. Таким образом, ответ будет специфичным для ОС.
  • Это явно невозможно на однопроцессорных машинах.
  • Это сложнее в отношении многопроцессорной машины. Согласно Относительность одновременности, "невозможно в абсолютном смысле сказать, происходят ли одновременно два события, если эти события разделены в космосе." Независимо от того, насколько близки ваши процессоры, они разделены в пространстве.
    • Если вы можете принять относительную одновременность, то, вероятно, проще просто имитировать ее, используя методы, обсуждаемые в других ответах.