如何在"完全"同时启动两个线程

fig*_*aro 84 java multithreading

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

甚至可能还是不可能?

Enn*_*oji 129

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

这不一定是CyclicBarrier,你也可以使用CountDownLatch甚至是锁.

这仍然不能确保它们已启动恰好在同一时间标准的JVM,但你可以得到相当接近.当你进行性能测试时,相当接近仍然很有用.例如,如果您尝试测量具有不同线程数的数据结构的吞吐量,则需要使用此类构造来获得最准确的结果.

在其他平台上,启动线程完全可以是一个非常有效的要求顺便说一句.

  • +1很好的思考;-)虽然它当然不会使线程在_exactly_实时同时启动(至少不是在单核芯片上,甚至在多核芯片上也不能保证),但是我想不出有什么方法可以做得更好. (5认同)

sam*_*aur 14

至少在单核计算机上是不可能的.但是你为什么要这样呢?即使您能够以完全相同的秒数启动两个线程,它们也会有不同的进展,因为调度不在您的控制之下.

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


aNi*_*ish 12

您可以使用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
    }
}
Run Code Online (Sandbox Code Playgroud)


emo*_*ory 6

  1. 据我了解,JVM主要将这些东西委托给操作系统.所以答案将是针对特定操作系统的.
  2. 在单处理器机器上显然是不可能的.
  3. 对于多处理器机器而言,它更复杂.根据同时性的相对论,"绝对意义上说,如果这些事件在空间中分离,两个事件是否同时发生是不可能的." 无论您的处理器有多近,它们都是空间分离的.
    1. 如果您可以接受相对同时性,那么使用其他响应中讨论的技术来模拟它可能更容易.

  • ……即使我们假设同时开始,每个线程都有自己的时间线,所有线程都是*并发*的,但不一定是并行的,因此任何人对线程同时性的假设都可能(将)在下一纳秒内(将)无效(无论哪个时间线)… (2认同)