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

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

Это даже возможно или невозможно?

84
задан danielad 24 October 2015 в 09:53
поделиться

4 ответа

Чтобы потоки запускались в одно и то же время (по крайней мере, насколько это возможно), вы можете использовать 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");

Это не обязательно должен быть CyclicBarrier , вы также можете использовать CountDownLatch или даже блокировку.

Это все еще не может гарантировать, что они запускаются точно одновременно на стандартных JVM, но вы можете подойти довольно близко. Подобраться довольно близко по-прежнему полезно, когда вы, например, проводите тесты производительности. Например, если вы пытаетесь измерить пропускную способность структуры данных с различным количеством обращающихся к ней потоков, вы хотите использовать такую ​​конструкцию, чтобы получить наиболее точный результат.

На других платформах запуск потоков ровно может быть очень допустимым требованием, кстати.

128
ответ дан 24 November 2019 в 08:34
поделиться

Это невозможно, по крайней мере, на одноядерном компьютере. Но зачем тебе это нужно? Даже если вы смогли запустить два потока точно в одну и ту же секунду, они будут выполняться по-разному, потому что планирование не находится в вашей власти.

Редактировать: (В ответ на некоторые комментарии) Совершенно допустимое требование синхронизировать состояние или прогресс нескольких потоков, и CyclicBarrier - отличный инструмент. Я ответил на вопрос, можно ли запускать несколько потоков в одно и то же время . CyclicBarrier гарантирует, что потоки продолжаются, когда они находятся точно в желаемом состоянии, но не гарантирует, что они начнутся или возобновятся в точно в то же время, хотя это может быть довольно Закрыть. В вопросе нет упоминания о необходимости синхронизации.

14
ответ дан 24 November 2019 в 08:34
поделиться

Для этого вы можете использовать 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
    }
}
12
ответ дан 24 November 2019 в 08:34
поделиться
  1. Насколько я понимаю, JVM в основном делегирует все это операционной системе. Так что ответ будет зависеть от ОС.
  2. Это явно невозможно на однопроцессорных машинах.
  3. С многопроцессорной машиной все сложнее. Согласно Относительности одновременности , «невозможно сказать в абсолютном смысле, происходят ли два события одновременно, если эти события разделены в пространстве». Независимо от того, насколько близко находятся ваши процессоры, они разделены пространством.
    1. Если вы можете принять относительную одновременность, то, вероятно, будет проще просто смоделировать ее, используя методы, описанные в других ответах.
6
ответ дан 24 November 2019 в 08:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: