繁体   English   中英

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

[英]How to start two threads at “exactly” the same time

线程应该在同一瞬间开始。 我明白,如果你执行thread1.start() ,在下一次执行thread2.start()之前需要几毫秒。

它甚至可能还是不可能?

要在完全相同的时间(至少尽可能好)启动线程,您可以使用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 上完全同时启动,但您可以非常接近。 当您进行例如性能测试时,变得非常接近仍然很有用。 例如,如果您尝试测量具有不同线程数的数据结构的吞吐量,您希望使用这种构造来获得最准确的结果。

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

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

编辑:(回应一些评论)同步多个线程的状态或进度是一个完全有效的要求, 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
    }
}
  1. 据我了解,JVM 主要将这些东西委托给操作系统。 所以答案将是特定于操作系统的。
  2. 这在单处理器机器上显然是不可能的。
  3. 相对于多处理器机器而言,情况更为复杂。 根据同时性相对论,“如果两个事件在空间上分开,就不可能从绝对意义上说这两个事件是否同时发生。” 无论您的处理器有多近,它们在空间上都是分开的。
    1. 如果您可以接受相对同时性,那么使用其他答复中讨论的技术来模拟它可能更容易。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM