Java 如何“完全”同时启动两个线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3376586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 22:42:21  来源:igfitidea点击:

How to start two threads at "exactly" the same time

javamultithreading

提问by figaro

The threads should start at same split second. I understand, if you do thread1.start(), it will take some milliseconds before the next execution of thread2.start().

线程应该在同一瞬间开始。我明白,如果你这样做thread1.start(),在下一次执行thread2.start().

Is it even possible or impossible?

它甚至可能还是不可能?

采纳答案by Enno Shioji

To start the threads at exactly the same time (at least as good as possible), you can use a CyclicBarrier:

要在完全相同的时间(至少尽可能好)启动线程,您可以使用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");

This doesn't have to be a CyclicBarrier, you could also use a CountDownLatchor even a lock.

这不一定是一个CyclicBarrier,您也可以使用一个CountDownLatch甚至一个锁。

This still can't make sure that they are started exactlyat the same time on standard JVMs, but you can get pretty close. Getting pretty close is still useful when you do for example performance tests. E.g., if you are trying to measure throughput of a data structure with different number of threads hitting it, you want to use this kind of construct to get the most accurate result possible.

这仍然无法确保它们在标准 JVM 上完全同时启动,但您可以非常接近。当您进行例如性能测试时,变得非常接近仍然很有用。例如,如果您尝试测量具有不同线程数的数据结构的吞吐量,您希望使用这种构造来获得最准确的结果。

On other platforms, starting threads exactlycan be a very valid requirement btw.

在其他平台上,准确地启动线程可能是一个非常有效的要求。

回答by samitgaur

It is not possible, at least on a single core computer. But why do you want that? Even if you were able to start two threads at exactly the same second, they will progress differently because scheduling is not in your control.

这是不可能的,至少在单核计算机上是不可能的。但你为什么要那样?即使您能够在完全相同的时间启动两个线程,它们的进度也会不同,因为调度不在您的控制范围内。

Edit: (In response to some of the comments) It is a perfectly valid requirement to synchronize the state or progressof multiple threads and CyclicBarrieris a great tool. I answered the question whether it is possible to start multiple threads at exactly the same time. CyclicBarrierwill guarantee that the threads proceed when they are exactly at the desired state but it doesn't guarantee that they will start or resume at exactlythe same time, although it might be pretty close. There's no mention of synchronization needs in the question.

编辑:(回应一些评论)同步多个线程的状态或进度是一个完全有效的要求,CyclicBarrier是一个很好的工具。我回答了是否可以完全同时启动多个线程的问题。CyclicBarrier将保证线程在它们完全处于所需状态时继续进行,但不保证它们将在完全相同的时间启动或恢复,尽管它可能非常接近。问题中没有提到同步需求。

回答by emory

  1. As I understand it, the JVM mostly delegates this stuff to the operating system. So the answer will be OS-specific.
  2. It is clearly impossible on a single-processor machines.
  3. It is more complicated with respect to a multi-processor machine. According to the Relativity of simultaneity, "it is impossible to say in an absolute sense whether two events occur at the same time if those events are separated in space." No matter how close your processors are, they are separated in space.
    1. If you can accept relative simultaneity, then it is probably easier just to simulate it using techniques discussed in other responses.
  1. 据我了解,JVM 主要将这些东西委托给操作系统。所以答案将是特定于操作系统的。
  2. 这在单处理器机器上显然是不可能的。
  3. 相对于多处理器机器而言,情况更为复杂。根据同时性相对论,“如果两个事件在空间上是分开的,就不可能在绝对意义上说这两个事件是否同时发生。” 无论您的处理器有多近,它们在空间上都是分开的。
    1. 如果您可以接受相对同时性,那么使用其他回答中讨论的技术来模拟它可能更容易。

回答by aNish

You could use a CountDownLatch for this. Please find below a sample. Though t1 and t2 are started, these threads keep waiting till the main thread counts down the latch. The number of countdowns required is mentioned in the constructor. Countdown latch can also be used to wait for threads to finish execution so that the main thread can proceed further(the reverse case). This class was included since Java 1.5.

您可以为此使用 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
    }
}