为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

阿晨1998 2019-11-12 11:01:25
线程应在同一瞬间开始。我知道,如果您这样做thread1.start(),则下次执行之前需要花费几毫秒的时间thread2.start()。可能还是不可能?
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

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


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


查看完整回答
反对 回复 2019-11-12
?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

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

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


查看完整回答
反对 回复 2019-11-12
?
江户川乱折腾

TA贡献1851条经验 获得超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

    }

}


查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 634 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信